dsh-edge 0.9.0 → 0.10.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 (56) hide show
  1. package/THIRD_PARTY_NOTICES.md +1318 -1075
  2. package/dist/assets/index-Df-65__b.js +110 -0
  3. package/dist/assets/index-b24khbeK.css +1 -0
  4. package/dist/assets/langs/{php-DDkx9sim.js → php-DJl5gRdb.js} +2 -2
  5. package/dist/assets/langs/{ruby-DCxyoPen.js → ruby-5eNB0pDK.js} +2 -2
  6. package/dist/assets/vendor-BNsW4eBh.css +1 -0
  7. package/dist/assets/vendor-CCJJTK99.js +411 -0
  8. package/dist/index.html +8 -8
  9. package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +1513 -77
  10. package/dist/plugins/@deepseek-ai/dsh-api-remotes/client.js +3608 -757
  11. package/dist/plugins/@deepseek-ai/dsh-api-session-controller/client.js +2777 -0
  12. package/dist/plugins/@deepseek-ai/dsh-api-workspace-controller/client.js +415 -0
  13. package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +1975 -7466
  14. package/dist/plugins/@deepseek-ai/dsh-client-locale/client.js +225 -76
  15. package/dist/plugins/@deepseek-ai/dsh-client-modules/client.js +67 -15
  16. package/dist/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js +270 -460
  17. package/dist/plugins/@deepseek-ai/dsh-client-ui-approval/client.js +292 -0
  18. package/dist/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js +42 -17
  19. package/dist/plugins/@deepseek-ai/dsh-client-ui-brand-official/client.js +7 -9
  20. package/dist/plugins/@deepseek-ai/dsh-client-ui-chat/client.js +8177 -0
  21. package/dist/plugins/@deepseek-ai/dsh-client-ui-commands/client.js +22 -10
  22. package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +14950 -8910
  23. package/dist/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js +161 -137
  24. package/dist/plugins/@deepseek-ai/dsh-client-ui-goal/client.js +6 -7
  25. package/dist/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js +268 -40
  26. package/dist/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js +1 -1
  27. package/dist/plugins/@deepseek-ai/dsh-client-ui-layout/client.js +45 -11
  28. package/dist/plugins/@deepseek-ai/dsh-client-ui-message-feedback/client.js +30 -58
  29. package/dist/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js +188 -89
  30. package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +105 -75
  31. package/dist/plugins/@deepseek-ai/dsh-client-ui-renderer/client.js +650 -188
  32. package/dist/plugins/@deepseek-ai/dsh-client-ui-schedule/client.js +307 -0
  33. package/dist/plugins/@deepseek-ai/dsh-client-ui-session/client.js +340 -0
  34. package/dist/plugins/@deepseek-ai/dsh-client-ui-settings/client.js +57 -50
  35. package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js +134 -69
  36. package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-models/client.js +575 -442
  37. package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +24 -11
  38. package/dist/plugins/@deepseek-ai/dsh-client-ui-skill/client.js +13 -9
  39. package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +44 -20
  40. package/dist/plugins/@deepseek-ai/dsh-client-ui-theme/client.js +265 -94
  41. package/dist/plugins/@deepseek-ai/dsh-client-ui-tool/client.js +899 -433
  42. package/dist/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js +1472 -613
  43. package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +249 -95
  44. package/dist/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js +5 -5
  45. package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +425 -146
  46. package/dist/plugins/@deepseek-ai/dsh-typert-registry/client.js +29 -14
  47. package/dist/plugins/dsh-edge-client-ui/client.js +28 -26
  48. package/package.json +62 -58
  49. package/scripts/verify-packed.mjs +1 -1
  50. package/worker/direct/index.js +2866 -1466
  51. package/worker/isolated/index.js +2438 -1038
  52. package/dist/assets/index-C6eRlFa6.css +0 -1
  53. package/dist/assets/index-ClqxG24t.js +0 -96
  54. package/dist/assets/vendor-CjyC-hUb.css +0 -1
  55. package/dist/assets/vendor-D22_Mp1f.js +0 -411
  56. package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +0 -10574
@@ -4,10 +4,160 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
- let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
7
+ let _deepseek_ai_cordis = require("@deepseek-ai/cordis");
8
+ let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
8
9
  let react_jsx_runtime = require("react/jsx-runtime");
9
10
  let react = require("react");
10
11
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
12
+ //#region lib/types/client/navigation.js
13
+ /** Workspace archive and directory UI capability. */
14
+ /** Structured directory failure exposed to directory UI consumers. */
15
+ var DirectoryBrowseError = class extends Error {
16
+ rpcError;
17
+ name = "DirectoryBrowseError";
18
+ /** @param rpcError - Host directory business failure. */
19
+ constructor(rpcError) {
20
+ super(`directory browse failed: ${rpcError.code}: ${rpcError.message}`);
21
+ this.rpcError = rpcError;
22
+ }
23
+ };
24
+ /** Implements Workspace archive and directory UI operations. */
25
+ var UiWorkspaceService = class extends _deepseek_ai_cordis.Service {
26
+ directoryPicker;
27
+ workspaces;
28
+ sessions;
29
+ connecting = /* @__PURE__ */ new Map();
30
+ /**
31
+ * @param ctx - Client root Context.
32
+ * @param directoryPicker - the directory-picking Remote namespace.
33
+ * @param workspaces - pure Workspace Controller.
34
+ * @param sessions - pure Session Controller.
35
+ */
36
+ constructor(ctx, directoryPicker, workspaces, sessions) {
37
+ super(ctx, "uiWorkspace");
38
+ this.directoryPicker = directoryPicker;
39
+ this.workspaces = workspaces;
40
+ this.sessions = sessions;
41
+ ctx.effect(() => this.watchNavigation(), "ui-workspace: Workspace navigation policy");
42
+ }
43
+ async connectWorkspace(workspaceId) {
44
+ const workspace = this.workspaces.list.getSnapshot().items.find((item) => item.workspaceId === workspaceId);
45
+ if (workspace === void 0) throw new Error(`uiWorkspace.connectWorkspace: unknown workspace ${workspaceId}`);
46
+ const inflight = this.connecting.get(workspaceId);
47
+ if (inflight !== void 0) return inflight;
48
+ const archived = this.workspaces.list.getSnapshot().archivedSessionIds;
49
+ const sessions = this.sessions.list.getSnapshot();
50
+ for (const id of sessions.ids) {
51
+ const summary = sessions.byId[id];
52
+ if (summary !== void 0 && summary.blank && summary.cwd === workspace.path && workspace.sessionIds.includes(summary.id) && !archived.includes(summary.id)) return summary.id;
53
+ }
54
+ const attempt = this.sessions.create({ workspaceId }).finally(() => {
55
+ this.connecting.delete(workspaceId);
56
+ });
57
+ this.connecting.set(workspaceId, attempt);
58
+ return attempt;
59
+ }
60
+ startSession(workspaceId) {
61
+ const workspace = this.workspaces.list.getSnapshot();
62
+ const sessions = this.sessions.list.getSnapshot();
63
+ const current = sessions.current;
64
+ const currentWorkspaceId = current === void 0 ? void 0 : workspace.items.find((item) => item.sessionIds.includes(current))?.workspaceId;
65
+ const recent = workspace.phase === "ready" && sessions.phase === "ready" ? recentWorkspace(workspace.items, sessions.byId) : void 0;
66
+ const target = workspaceId ?? currentWorkspaceId ?? recent;
67
+ if (target === void 0) {
68
+ this.sessions.clear();
69
+ return;
70
+ }
71
+ this.connectWorkspace(target).then((sessionId) => {
72
+ this.sessions.open(sessionId);
73
+ }, (reason) => {
74
+ console.warn("new session failed:", reason);
75
+ });
76
+ }
77
+ async archiveSession(sessionId) {
78
+ await this.workspaces.archiveSession(sessionId);
79
+ }
80
+ async pickDirectory() {
81
+ const result = await this.directoryPicker.pick();
82
+ if (!result.ok) throw new Error(`directory picker failed: ${result.error.message}`);
83
+ return result.value;
84
+ }
85
+ async listDirectory(path, signal) {
86
+ const result = await this.directoryPicker.list(path, signal);
87
+ if (!result.ok) throw new DirectoryBrowseError(result.error);
88
+ return result.value;
89
+ }
90
+ async createDirectory(path, name) {
91
+ const result = await this.directoryPicker.createDirectory(path, name);
92
+ if (!result.ok) throw new DirectoryBrowseError(result.error);
93
+ return result.value;
94
+ }
95
+ watchNavigation() {
96
+ let initial = "waiting";
97
+ let disposed = false;
98
+ const reconcile = () => {
99
+ if (disposed) return;
100
+ if (this.clearArchivedCurrent()) return;
101
+ if (initial !== "waiting") return;
102
+ const workspace = this.workspaces.list.getSnapshot();
103
+ const sessions = this.sessions.list.getSnapshot();
104
+ if (workspace.phase !== "ready" || sessions.phase !== "ready") return;
105
+ if (sessions.current !== void 0) {
106
+ initial = "done";
107
+ return;
108
+ }
109
+ const target = recentWorkspace(workspace.items, sessions.byId);
110
+ if (target === void 0) {
111
+ initial = "done";
112
+ return;
113
+ }
114
+ initial = "connecting";
115
+ this.connectWorkspace(target).then((sessionId) => {
116
+ if (disposed) return;
117
+ if (this.sessions.list.getSnapshot().current === void 0) this.sessions.open(sessionId);
118
+ initial = "done";
119
+ }, (reason) => {
120
+ if (disposed) return;
121
+ initial = "waiting";
122
+ console.warn("initial workspace selection failed:", reason);
123
+ });
124
+ };
125
+ const disposeWorkspaces = this.workspaces.list.subscribe(reconcile);
126
+ const disposeSessions = this.sessions.list.subscribe(reconcile);
127
+ reconcile();
128
+ return () => {
129
+ disposed = true;
130
+ disposeSessions();
131
+ disposeWorkspaces();
132
+ };
133
+ }
134
+ /** @returns true when an archived current selection was cleared. */
135
+ clearArchivedCurrent() {
136
+ const current = this.sessions.list.getSnapshot().current;
137
+ if (current === void 0 || !this.workspaces.list.getSnapshot().archivedSessionIds.includes(current)) return false;
138
+ this.sessions.clear();
139
+ return true;
140
+ }
141
+ };
142
+ /** Stable tie-breaking follows Host Workspace order. */
143
+ function recentWorkspace(workspaces, sessions) {
144
+ let selected;
145
+ let selectedTime = Number.NEGATIVE_INFINITY;
146
+ for (const workspace of workspaces) {
147
+ let latest = Number.NEGATIVE_INFINITY;
148
+ for (const sessionId of workspace.sessionIds) {
149
+ const session = sessions[sessionId];
150
+ if (session !== void 0) latest = Math.max(latest, session.updatedAt);
151
+ }
152
+ if (latest === Number.NEGATIVE_INFINITY) latest = Date.parse(workspace.createdAt);
153
+ if (selected === void 0 || latest > selectedTime) {
154
+ selected = workspace.workspaceId;
155
+ selectedTime = latest;
156
+ }
157
+ }
158
+ return selected;
159
+ }
160
+ //#endregion
11
161
  //#region lib/types/client/stores.js
12
162
  /**
13
163
  * The workspace browser's viewing store: the session-list grouping mode,
@@ -23,7 +173,7 @@ window.__ModuleLoader__.load({
23
173
  * @returns the store handle (spec + type + identity + factory in one).
24
174
  */
25
175
  function createWorkspaceViewStore() {
26
- return (0, _deepseek_ai_dsh_client_runtime_client.defineStore)({
176
+ return (0, _deepseek_ai_dsh_client_store.defineStore)({
27
177
  init: () => ({
28
178
  groupBy: "workspace",
29
179
  orderBy: "updated",
@@ -73,18 +223,82 @@ window.__ModuleLoader__.load({
73
223
  for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
74
224
  return n;
75
225
  }
76
- /** Display label for the ungrouped bucket row. */
77
- const UNGROUPED_LABEL = "Ungrouped";
226
+ //#endregion
227
+ //#region ../../util/workspace-path/src/index.ts
228
+ /**
229
+ * Browser-safe Workspace path and display helpers.
230
+ * @module @deepseek-ai/dsh-util-workspace-path
231
+ */
232
+ /** Whether a path uses a Windows drive or UNC prefix. */
233
+ function isWindowsStylePath(value) {
234
+ return /^[A-Za-z]:[/\\]/.test(value) || value.startsWith("\\\\");
235
+ }
236
+ /**
237
+ * Abbreviate a POSIX home directory for display.
238
+ * @param path - Absolute or already-short display path.
239
+ * @param home - Host account home; absent skips abbreviation.
240
+ * @returns `~` or `~/…` for the POSIX home and its descendants, otherwise `path`.
241
+ */
242
+ function abbreviateHomePath(path, home) {
243
+ if (home === void 0 || home === "") return path;
244
+ if (isWindowsStylePath(path) || isWindowsStylePath(home)) return path;
245
+ const root = home.replace(/\/+$/, "");
246
+ if (root === "" || root === "/") return path;
247
+ if (path.replace(/\/+$/, "") === root) return "~";
248
+ if (path.startsWith(`${root}/`)) return `~${path.slice(root.length)}`;
249
+ return path;
250
+ }
251
+ /**
252
+ * Read the final non-empty segment of a Workspace path for display.
253
+ * Workspace-label surfaces use this helper instead of deriving another basename.
254
+ * @param path - Workspace directory path using POSIX or Windows separators.
255
+ * @returns the final segment, or an empty string for a separator-only path.
256
+ */
257
+ function workspaceTitleOf(path) {
258
+ const trimmed = path.replace(/[/\\]+$/, "");
259
+ const separator = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
260
+ return trimmed.slice(separator + 1);
261
+ }
262
+ //#endregion
263
+ //#region lib/types/client/subagent-lineage.js
264
+ /** UI Workspace-owned projection of descendant counts from Session summaries. */
265
+ /**
266
+ * Index uninterrupted subagent descendants under each ancestor.
267
+ * @param summaries - Session summaries keyed by id.
268
+ * @returns descendant totals keyed by possible parent id.
269
+ */
270
+ function indexSubagentDescendants(summaries) {
271
+ const indexed = /* @__PURE__ */ new Map();
272
+ for (const descendant of Object.values(summaries)) {
273
+ if (descendant.origin !== "subagent") continue;
274
+ const seen = /* @__PURE__ */ new Set();
275
+ let current = descendant;
276
+ while (current?.origin === "subagent" && current.parentId !== void 0 && !seen.has(current.id)) {
277
+ seen.add(current.id);
278
+ const aggregate = indexed.get(current.parentId);
279
+ if (aggregate === void 0) indexed.set(current.parentId, {
280
+ count: 1,
281
+ runningCount: descendant.running ? 1 : 0
282
+ });
283
+ else {
284
+ aggregate.count += 1;
285
+ if (descendant.running) aggregate.runningCount += 1;
286
+ }
287
+ current = summaries[current.parentId];
288
+ }
289
+ }
290
+ return indexed;
291
+ }
78
292
  /**
79
293
  * Directory display label: basename of the path (both separators accepted).
80
294
  * Ungrouped-bucket fallback for surfaces without a workspace title.
81
295
  * @param cwd - directory path, or undefined for the ungrouped bucket.
82
- * @returns basename, the raw cwd when it has no basename, or the ungrouped label.
296
+ * @returns basename, the raw cwd when it has no basename, or an empty ungrouped marker.
83
297
  */
84
298
  function workspaceLabel(cwd) {
85
- if (cwd === void 0 || cwd === "") return UNGROUPED_LABEL;
86
- const base = cwd.replace(/[/\\]+$/, "").split(/[/\\]/).pop();
87
- return base !== void 0 && base !== "" ? base : cwd;
299
+ if (cwd === void 0 || cwd === "") return "";
300
+ const base = workspaceTitleOf(cwd);
301
+ return base !== "" ? base : cwd;
88
302
  }
89
303
  /** Recency comparator: newest first, id as the deterministic tiebreak (ids are unique per group). */
90
304
  function byRecency(a, b) {
@@ -106,7 +320,11 @@ window.__ModuleLoader__.load({
106
320
  * and the renderer localizes its display label.
107
321
  */
108
322
  function sessionTitle(session) {
109
- return session.blank ? "New Session" : session.displayTitle;
323
+ return session.blank ? "" : session.displayTitle;
324
+ }
325
+ /** The list projection alone owns the best-effort active-Schedule indicator. */
326
+ function hasActiveSchedule(session) {
327
+ return (session.projectionValues?.schedule?.length ?? 0) > 0;
110
328
  }
111
329
  /** Build one group without projecting session lineage into presentation. */
112
330
  function buildGroup(key, workspaceId, cwd, createdAt, label, members, order) {
@@ -159,10 +377,20 @@ window.__ModuleLoader__.load({
159
377
  groups.push(buildGroup(workspace.workspaceId, workspace.workspaceId, workspace.path, Date.parse(workspace.createdAt), workspace.title, members, "account"));
160
378
  }
161
379
  const stray = list.ids.map((id) => list.byId[id]).filter((s) => s !== void 0 && !accounted.has(s.id) && sessionVisible(s, list.current, archived));
162
- if (stray.length > 0) groups.push(buildGroup("", void 0, void 0, void 0, UNGROUPED_LABEL, ungroupedOrder === void 0 ? stray : orderedUngrouped(stray, ungroupedOrder), ungroupedOrder === void 0 ? "recency" : "account"));
380
+ if (stray.length > 0) groups.push(buildGroup("", void 0, void 0, void 0, "", ungroupedOrder === void 0 ? stray : orderedUngrouped(stray, ungroupedOrder), ungroupedOrder === void 0 ? "recency" : "account"));
163
381
  return groups;
164
382
  }
165
- function sessionNode(s, descendants) {
383
+ /** Keep navigation presentation independent from domain-owned interaction objects. */
384
+ function visiblePendingKind(kind) {
385
+ switch (kind) {
386
+ case "approval":
387
+ case "plan-review":
388
+ case "question": return kind;
389
+ default: return;
390
+ }
391
+ }
392
+ function sessionNode(s, descendants, pendingInteractions) {
393
+ const pendingInteraction = visiblePendingKind(pendingInteractions.get(s.id)?.kind);
166
394
  return {
167
395
  id: s.id,
168
396
  title: sessionTitle(s),
@@ -170,8 +398,9 @@ window.__ModuleLoader__.load({
170
398
  running: s.running,
171
399
  runningSubagentCount: descendants.get(s.id)?.runningCount ?? 0,
172
400
  completed: s.completed === true,
401
+ hasActiveSchedule: hasActiveSchedule(s),
173
402
  updatedAt: s.updatedAt,
174
- ...s.pendingInteraction === void 0 ? {} : { pendingInteraction: s.pendingInteraction }
403
+ ...pendingInteraction === void 0 ? {} : { pendingInteraction }
175
404
  };
176
405
  }
177
406
  /**
@@ -185,13 +414,14 @@ window.__ModuleLoader__.load({
185
414
  * @param list - sessions list snapshot (`current` feeds containsCurrent).
186
415
  * @param workspaces - real workspaces in stable Host order.
187
416
  * @param archivedSessionIds - registry-global archive set.
417
+ * @param pendingInteractions - pending UI interactions by Session.
188
418
  * @param view - local expansion arrays.
189
419
  * @returns group sections in render order.
190
420
  */
191
- function deriveGroups(list, workspaces, archivedSessionIds, view) {
421
+ function deriveGroups(list, workspaces, archivedSessionIds, pendingInteractions, view) {
192
422
  const archived = new Set(archivedSessionIds);
193
423
  const expandedGroups = new Set(view.expandedGroups);
194
- const descendants = (0, _deepseek_ai_dsh_client_runtime_client.indexSubagentDescendants)(list.byId);
424
+ const descendants = indexSubagentDescendants(list.byId);
195
425
  const currentGroup = list.current === void 0 ? void 0 : workspaces.find((w) => w.sessionIds.includes(list.current))?.workspaceId ?? "";
196
426
  const groups = [];
197
427
  for (const g of groupByWorkspace(list, workspaces, archived, view.ungroupedOrder)) {
@@ -205,7 +435,7 @@ window.__ModuleLoader__.load({
205
435
  sessionCount: g.sessions.length,
206
436
  expanded,
207
437
  containsCurrent: g.key === currentGroup,
208
- sessions: expanded ? g.sessions.map((session) => sessionNode(session, descendants)) : []
438
+ sessions: expanded ? g.sessions.map((session) => sessionNode(session, descendants, pendingInteractions)) : []
209
439
  });
210
440
  }
211
441
  return groups;
@@ -217,11 +447,12 @@ window.__ModuleLoader__.load({
217
447
  * (see {@link deriveSearchResults}).
218
448
  * @param list - sessions list snapshot.
219
449
  * @param archivedSessionIds - registry-global archive set.
450
+ * @param pendingInteractions - pending UI interactions by Session.
220
451
  * @returns flat rows in render order.
221
452
  */
222
- function deriveFlat(list, archivedSessionIds) {
453
+ function deriveFlat(list, archivedSessionIds, pendingInteractions) {
223
454
  const archived = new Set(archivedSessionIds);
224
- const descendants = (0, _deepseek_ai_dsh_client_runtime_client.indexSubagentDescendants)(list.byId);
455
+ const descendants = indexSubagentDescendants(list.byId);
225
456
  const rows = [];
226
457
  for (const id of list.ids) {
227
458
  const s = list.byId[id];
@@ -229,7 +460,7 @@ window.__ModuleLoader__.load({
229
460
  rows.push(s);
230
461
  }
231
462
  rows.sort(byRecency);
232
- return rows.map((session) => sessionNode(session, descendants));
463
+ return rows.map((session) => sessionNode(session, descendants, pendingInteractions));
233
464
  }
234
465
  /**
235
466
  * Merge immediate title/Workspace substring matches with ranked Host content
@@ -239,18 +470,19 @@ window.__ModuleLoader__.load({
239
470
  * @param workspaces - Workspace membership and display labels.
240
471
  * @param query - caller text; surrounding whitespace is ignored.
241
472
  * @param archivedSessionIds - registry-global archive set (members never match).
473
+ * @param pendingInteractions - pending UI interactions by Session.
242
474
  * @param content - ranked Host content-search page.
243
475
  * @param limit - protocol-owned maximum merged row count.
244
476
  * @returns bounded deduplicated flat rows and a refine-query hint bit.
245
477
  */
246
- function deriveSearchResults(list, workspaces, query, archivedSessionIds, content, limit) {
478
+ function deriveSearchResults(list, workspaces, query, archivedSessionIds, pendingInteractions, content, limit) {
247
479
  const q = query.trim().toLowerCase();
248
480
  if (q === "") return {
249
481
  items: [],
250
482
  hasMore: false
251
483
  };
252
484
  const archived = new Set(archivedSessionIds);
253
- const descendants = (0, _deepseek_ai_dsh_client_runtime_client.indexSubagentDescendants)(list.byId);
485
+ const descendants = indexSubagentDescendants(list.byId);
254
486
  const workspaceBySession = /* @__PURE__ */ new Map();
255
487
  for (const workspace of workspaces) for (const sessionId of workspace.sessionIds) if (!workspaceBySession.has(sessionId)) workspaceBySession.set(sessionId, workspace.title);
256
488
  const labelOf = (summary) => workspaceBySession.get(summary.id) ?? workspaceLabel(summary.cwd);
@@ -278,60 +510,25 @@ window.__ModuleLoader__.load({
278
510
  return {
279
511
  items: ordered.slice(0, limit).map((summary) => {
280
512
  const match = contentBySession.get(summary.id);
513
+ const pendingInteraction = visiblePendingKind(pendingInteractions.get(summary.id)?.kind);
281
514
  return {
282
515
  id: summary.id,
283
516
  title: sessionTitle(summary),
284
517
  workspace: labelOf(summary),
285
518
  running: summary.running,
286
519
  runningSubagentCount: descendants.get(summary.id)?.runningCount ?? 0,
287
- ...summary.pendingInteraction === void 0 ? {} : { pendingInteraction: summary.pendingInteraction },
520
+ ...pendingInteraction === void 0 ? {} : { pendingInteraction },
288
521
  completed: summary.completed === true,
522
+ hasActiveSchedule: hasActiveSchedule(summary),
289
523
  ...match === void 0 ? {} : { snippet: match.snippet }
290
524
  };
291
525
  }),
292
526
  hasMore: content.hasMore || ordered.length > limit
293
527
  };
294
528
  }
295
- /**
296
- * Compact relative time for session rows, as a structured bucket the
297
- * renderer localizes ("now"/"5min"/"3h"/"2d"/"4mo"/"1y" in en).
298
- * @param updatedAt - epoch ms of the session's last activity.
299
- * @param now - current epoch ms (injected for pure rendering).
300
- * @returns the row's trailing time bucket and magnitude.
301
- */
302
- function relativeTime(updatedAt, now) {
303
- const MIN = 6e4;
304
- const HOUR = 36e5;
305
- const DAY = 864e5;
306
- const diff = Math.max(0, now - updatedAt);
307
- if (diff < MIN) return {
308
- unit: "now",
309
- n: 0
310
- };
311
- if (diff < HOUR) return {
312
- unit: "minutes",
313
- n: Math.floor(diff / MIN)
314
- };
315
- if (diff < DAY) return {
316
- unit: "hours",
317
- n: Math.floor(diff / HOUR)
318
- };
319
- if (diff < 30 * DAY) return {
320
- unit: "days",
321
- n: Math.floor(diff / DAY)
322
- };
323
- if (diff < 365 * DAY) return {
324
- unit: "months",
325
- n: Math.floor(diff / (30 * DAY))
326
- };
327
- return {
328
- unit: "years",
329
- n: Math.floor(diff / (365 * DAY))
330
- };
331
- }
332
529
  //#endregion
333
530
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-workspace/src/client/rows/Rows.module.css.mjs
334
- const css$2 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;gap:6px;padding:0 8px;display:flex}.YDXeBa_projectRow:hover,.YDXeBa_sessionRow:hover,.YDXeBa_sessionRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultRow{box-sizing:border-box;cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:8px;flex-direction:column;align-items:stretch;padding:4px 8px;display:flex}.YDXeBa_searchResultRow:hover,.YDXeBa_searchResultRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultHeading{align-items:center;min-width:0;display:flex}.YDXeBa_searchResultTitle{text-overflow:ellipsis;white-space:nowrap;min-width:0;margin-left:4px;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_searchResultMeta{align-items:center;gap:6px;min-width:0;margin-left:20px;display:flex}.YDXeBa_searchResultWorkspace,.YDXeBa_searchResultSnippet{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.YDXeBa_searchResultWorkspace{max-width:40%;color:var(--dsw-alias-label-tertiary);flex:none}.YDXeBa_searchResultSnippet{min-width:0;color:var(--dsw-alias-label-secondary);flex:1}.YDXeBa_projectRow{box-sizing:border-box;align-items:center;height:34px}.YDXeBa_projectRow .YDXeBa_rowActions{height:20px}.YDXeBa_sessionRow{height:32px;animation:YDXeBa_row-in .15s var(--ds-ease-in-out);gap:0}.YDXeBa_sessionRow .YDXeBa_title{margin:0 6px 0 4px}.YDXeBa_flatSessionRowWithoutStatus .YDXeBa_title{margin-left:0}@keyframes YDXeBa_row-in{0%{opacity:0}}.YDXeBa_slot{width:16px;height:20px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.YDXeBa_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.YDXeBa_folderActive{color:var(--dsw-alias-state-business-primary)}.YDXeBa_projectRow .YDXeBa_chevron{display:none}.YDXeBa_projectRow:hover .YDXeBa_chevron{display:inline-flex}.YDXeBa_projectRow:hover .YDXeBa_folder{display:none}.YDXeBa_arrow{transition:transform .15s var(--ds-ease-in-out)}.YDXeBa_arrowOpen{transform:rotate(90deg)}.YDXeBa_projectText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.YDXeBa_title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_renameInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-elevated-fill);min-width:0;color:inherit;border-radius:4px;outline:none;padding:0 2px;font-size:14px;line-height:20px}.YDXeBa_sessionRow .YDXeBa_title{flex:1}.YDXeBa_meta{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:20px;overflow:hidden}.YDXeBa_time{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:20px}.YDXeBa_dot{flex:none}.YDXeBa_rowActions{flex:none;align-items:center;gap:12px;display:none}.YDXeBa_projectRow:hover .YDXeBa_rowActions,.YDXeBa_sessionRow:hover .YDXeBa_rowActions,.YDXeBa_projectRow.YDXeBa_menuOpen .YDXeBa_rowActions,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_rowActions{display:inline-flex}.YDXeBa_sessionRow:hover .YDXeBa_time,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_time{display:none}.YDXeBa_projectRow.YDXeBa_menuOpen,.YDXeBa_sessionRow.YDXeBa_menuOpen{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_sessionRow.YDXeBa_dropBefore,.YDXeBa_sessionRow.YDXeBa_dropAfter{position:relative}.YDXeBa_sessionRow.YDXeBa_dropBefore:before,.YDXeBa_sessionRow.YDXeBa_dropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.YDXeBa_sessionRow.YDXeBa_dropBefore:before{top:-7px}.YDXeBa_sessionRow.YDXeBa_dropAfter:after{bottom:-7px}.YDXeBa_hoverContent{flex-direction:column;gap:8px;display:flex}.YDXeBa_hoverTitle{color:#fff;overflow-wrap:break-word;font-size:14px;line-height:20px}.YDXeBa_hoverPath{color:#cfd3d6;word-break:break-all;font-size:12px;line-height:16px}.YDXeBa_hoverTime{color:#cfd3d6;font-size:12px;line-height:16px}.YDXeBa_hoverStatus{color:#adb2b8;align-items:center;gap:8px;font-size:12px;line-height:20px;display:flex}.YDXeBa_iconButton{cursor:pointer;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.YDXeBa_iconButton:hover{color:var(--dsw-alias-label-primary)}.YDXeBa_chevron{color:var(--dsw-alias-label-caption)}@media (prefers-reduced-motion:reduce){.YDXeBa_sessionRow,.YDXeBa_arrow{transition:none;animation:none}}";
531
+ const css$2 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;gap:6px;padding:0 8px;display:flex}.YDXeBa_projectRow:hover,.YDXeBa_sessionRow:hover,.YDXeBa_sessionRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultRow{box-sizing:border-box;cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:8px;flex-direction:column;align-items:stretch;padding:4px 8px;display:flex}.YDXeBa_searchResultRow:hover,.YDXeBa_searchResultRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultHeading{align-items:center;min-width:0;display:flex}.YDXeBa_searchResultTitle{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;margin-left:4px;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_searchResultMeta{align-items:center;gap:6px;min-width:0;margin-left:20px;display:flex}.YDXeBa_searchResultWorkspace,.YDXeBa_searchResultSnippet{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.YDXeBa_searchResultWorkspace{max-width:40%;color:var(--dsw-alias-label-tertiary);flex:none}.YDXeBa_searchResultSnippet{min-width:0;color:var(--dsw-alias-label-secondary);flex:1}.YDXeBa_projectRow{box-sizing:border-box;align-items:center;height:34px}.YDXeBa_projectRow .YDXeBa_rowActions{height:20px}.YDXeBa_sessionRow{height:32px;animation:YDXeBa_row-in .15s var(--ds-ease-in-out);gap:0}.YDXeBa_sessionRow .YDXeBa_title{margin:0 6px 0 4px}.YDXeBa_flatSessionRowWithoutStatus .YDXeBa_title{margin-left:0}@keyframes YDXeBa_row-in{0%{opacity:0}}.YDXeBa_slot{width:16px;height:20px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.YDXeBa_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.YDXeBa_folderActive{color:var(--dsw-alias-state-business-primary)}.YDXeBa_projectRow .YDXeBa_chevron{display:none}.YDXeBa_projectRow:hover .YDXeBa_chevron{display:inline-flex}.YDXeBa_projectRow:hover .YDXeBa_folder{display:none}.YDXeBa_arrow{transition:transform .15s var(--ds-ease-in-out)}.YDXeBa_arrowOpen{transform:rotate(90deg)}.YDXeBa_projectText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.YDXeBa_title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_renameInput{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-button-elevated-fill);min-width:0;color:inherit;border-radius:4px;outline:none;padding:0 2px;font-size:14px;line-height:20px}.YDXeBa_sessionRow .YDXeBa_title{flex:1}.YDXeBa_meta{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:20px;overflow:hidden}.YDXeBa_time{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:20px}.YDXeBa_scheduleIndicator{width:16px;height:20px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;margin-right:6px;display:inline-flex}.YDXeBa_searchScheduleIndicator{margin-left:4px;margin-right:0}.YDXeBa_dot{flex:none}.YDXeBa_rowActions{flex:none;align-items:center;gap:12px;display:none}.YDXeBa_projectRow:hover .YDXeBa_rowActions,.YDXeBa_sessionRow:hover .YDXeBa_rowActions,.YDXeBa_projectRow.YDXeBa_menuOpen .YDXeBa_rowActions,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_rowActions{display:inline-flex}.YDXeBa_sessionRow:hover .YDXeBa_time,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_time{display:none}.YDXeBa_projectRow.YDXeBa_menuOpen,.YDXeBa_sessionRow.YDXeBa_menuOpen{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_sessionRow.YDXeBa_dropBefore,.YDXeBa_sessionRow.YDXeBa_dropAfter{position:relative}.YDXeBa_sessionRow.YDXeBa_dropBefore:before,.YDXeBa_sessionRow.YDXeBa_dropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.YDXeBa_sessionRow.YDXeBa_dropBefore:before{top:-7px}.YDXeBa_sessionRow.YDXeBa_dropAfter:after{bottom:-7px}.YDXeBa_hoverContent{flex-direction:column;gap:8px;display:flex}.YDXeBa_hoverTitle{color:#fff;overflow-wrap:break-word;font-size:14px;line-height:20px}.YDXeBa_hoverPath{color:#cfd3d6;word-break:break-all;font-size:12px;line-height:16px}.YDXeBa_hoverTime{color:#cfd3d6;font-size:12px;line-height:16px}.YDXeBa_hoverStatus{color:#adb2b8;align-items:center;gap:8px;font-size:12px;line-height:20px;display:flex}.YDXeBa_iconButton{cursor:pointer;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.YDXeBa_iconButton:hover{color:var(--dsw-alias-label-primary)}.YDXeBa_chevron{color:var(--dsw-alias-label-caption)}@media (prefers-reduced-motion:reduce){.YDXeBa_sessionRow,.YDXeBa_arrow{transition:none;animation:none}}";
335
532
  const tagId$2 = "@deepseek-ai/dsh-client-ui-workspace/Rows.module.css";
336
533
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
337
534
  const tag = document.createElement("style");
@@ -363,12 +560,14 @@ window.__ModuleLoader__.load({
363
560
  "renameInput": "YDXeBa_renameInput",
364
561
  "row-in": "YDXeBa_row-in",
365
562
  "rowActions": "YDXeBa_rowActions",
563
+ "scheduleIndicator": "YDXeBa_scheduleIndicator",
366
564
  "searchResultHeading": "YDXeBa_searchResultHeading",
367
565
  "searchResultMeta": "YDXeBa_searchResultMeta",
368
566
  "searchResultRow": "YDXeBa_searchResultRow",
369
567
  "searchResultSnippet": "YDXeBa_searchResultSnippet",
370
568
  "searchResultTitle": "YDXeBa_searchResultTitle",
371
569
  "searchResultWorkspace": "YDXeBa_searchResultWorkspace",
570
+ "searchScheduleIndicator": "YDXeBa_searchScheduleIndicator",
372
571
  "selected": "YDXeBa_selected",
373
572
  "sessionRow": "YDXeBa_sessionRow",
374
573
  "slot": "YDXeBa_slot",
@@ -391,12 +590,12 @@ window.__ModuleLoader__.load({
391
590
  }
392
591
  /** Localized compact relative time ("刚刚"/"5分钟" in zh, "now"/"5min" in en). */
393
592
  function timeLabel(updatedAt, now, t) {
394
- const { unit, n } = relativeTime(updatedAt, now);
593
+ const { unit, n } = (0, _deepseek_ai_dsh_client_ui_primitives.relativeTime)(updatedAt, now);
395
594
  return unit === "now" ? t("time.now") : t(`time.${unit}`, { n });
396
595
  }
397
596
  /** Hover-card variant: distances wrap in the ago template; the now bucket stays bare (no "now ago"). */
398
597
  function hoverTimeLabel(updatedAt, now, t) {
399
- const { unit, n } = relativeTime(updatedAt, now);
598
+ const { unit, n } = (0, _deepseek_ai_dsh_client_ui_primitives.relativeTime)(updatedAt, now);
400
599
  return unit === "now" ? t("time.now") : t("time.ago", { t: t(`time.${unit}`, { n }) });
401
600
  }
402
601
  /**
@@ -504,7 +703,7 @@ window.__ModuleLoader__.load({
504
703
  items: workspaceMenuItems,
505
704
  onSelect: (id) => {
506
705
  setMenuOpen(false);
507
- /* v8 ignore next -- workspaceMenuItems carries exactly these two rows today. */
706
+ /* v8 ignore next -- Menu can emit only the rename and delete rows supplied above. */
508
707
  if (id !== "rename" && id !== "delete") return;
509
708
  if (id === "rename") actions.rename();
510
709
  else actions.delete();
@@ -539,7 +738,7 @@ window.__ModuleLoader__.load({
539
738
  anchor: ownRow,
540
739
  content: (0, react_jsx_runtime.jsx)(WorkspaceHoverContent, {
541
740
  label: row.label,
542
- cwd: row.cwd === void 0 ? void 0 : (0, _deepseek_ai_dsh_client_runtime_client.abbreviateHomePath)(row.cwd, home),
741
+ cwd: row.cwd === void 0 ? void 0 : abbreviateHomePath(row.cwd, home),
543
742
  createdAt: row.createdAt,
544
743
  t
545
744
  }),
@@ -611,6 +810,17 @@ window.__ModuleLoader__.load({
611
810
  children: status.label
612
811
  }, status.label))] });
613
812
  }
813
+ /** Non-interactive active-Schedule marker; the enclosing row remains the only action. */
814
+ function ActiveScheduleIndicator({ t, search = false }) {
815
+ const label = t("schedule.active");
816
+ return (0, react_jsx_runtime.jsx)("span", {
817
+ className: clsx(Rows_module_css_default.scheduleIndicator, search && Rows_module_css_default.searchScheduleIndicator),
818
+ role: "img",
819
+ "aria-label": label,
820
+ title: label,
821
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconAlarmClockOutline16, {})
822
+ });
823
+ }
614
824
  /** Hover-card body: full title, relative time, and every relevant live status. */
615
825
  function SessionHoverContent({ node, now, t }) {
616
826
  const statuses = sessionStatuses(node, t);
@@ -656,18 +866,25 @@ window.__ModuleLoader__.load({
656
866
  },
657
867
  children: [(0, react_jsx_runtime.jsxs)("span", {
658
868
  className: Rows_module_css_default.searchResultHeading,
659
- children: [(0, react_jsx_runtime.jsx)("span", {
660
- className: Rows_module_css_default.slot,
661
- children: (primaryStatus.state !== "done" || result.completed) && (0, react_jsx_runtime.jsx)(SessionStatusDots, { statuses })
662
- }), (0, react_jsx_runtime.jsx)("span", {
663
- className: Rows_module_css_default.searchResultTitle,
664
- children: result.title
665
- })]
869
+ children: [
870
+ (0, react_jsx_runtime.jsx)("span", {
871
+ className: Rows_module_css_default.slot,
872
+ children: (primaryStatus.state !== "done" || result.completed) && (0, react_jsx_runtime.jsx)(SessionStatusDots, { statuses })
873
+ }),
874
+ (0, react_jsx_runtime.jsx)("span", {
875
+ className: Rows_module_css_default.searchResultTitle,
876
+ children: result.title
877
+ }),
878
+ result.hasActiveSchedule && (0, react_jsx_runtime.jsx)(ActiveScheduleIndicator, {
879
+ t,
880
+ search: true
881
+ })
882
+ ]
666
883
  }), (0, react_jsx_runtime.jsxs)("span", {
667
884
  className: Rows_module_css_default.searchResultMeta,
668
885
  children: [(0, react_jsx_runtime.jsx)("span", {
669
886
  className: Rows_module_css_default.searchResultWorkspace,
670
- children: result.workspace
887
+ children: result.workspace || t("group.ungrouped")
671
888
  }), result.snippet !== void 0 && (0, react_jsx_runtime.jsx)("span", {
672
889
  className: Rows_module_css_default.searchResultSnippet,
673
890
  children: result.snippet
@@ -749,6 +966,7 @@ window.__ModuleLoader__.load({
749
966
  className: Rows_module_css_default.title,
750
967
  children: title
751
968
  }),
969
+ row.hasActiveSchedule && (0, react_jsx_runtime.jsx)(ActiveScheduleIndicator, { t }),
752
970
  !row.blank && (0, react_jsx_runtime.jsx)("span", {
753
971
  className: Rows_module_css_default.time,
754
972
  children: timeLabel(row.updatedAt, now, t)
@@ -965,8 +1183,8 @@ window.__ModuleLoader__.load({
965
1183
  });
966
1184
  }
967
1185
  //#endregion
968
- //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-workspace/src/client/WorkspaceBrowser.module.css.mjs
969
- const css = ".qDHVXG_root{--dsh-session-list-edge-inset:var(--dsh-sidebar-inline-padding);--dsh-session-list-scrollbar-width:8px;--dsh-session-list-scrollbar-offset:2px;box-sizing:border-box;min-height:0;padding-right:var(--dsh-session-list-edge-inset);flex-direction:column;flex:1;display:flex}.qDHVXG_root.qDHVXG_rail{padding-right:0}.qDHVXG_iconButton{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.qDHVXG_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.qDHVXG_sectionHeader{box-sizing:border-box;height:36px;color:var(--dsw-alias-label-tertiary);border-radius:12px;flex:none;justify-content:flex-end;align-items:center;gap:4px;margin-bottom:4px;padding-left:4px;display:flex;overflow:hidden}.qDHVXG_root:not(.qDHVXG_rail) .qDHVXG_sectionHeader{margin-top:2px;margin-right:-4px}.qDHVXG_sectionLabel{white-space:nowrap;opacity:1;visibility:visible;min-width:0;max-width:45%;transition:max-width .18s var(--ds-ease-in-out), margin-right .18s var(--ds-ease-in-out), opacity .12s var(--ds-ease-in-out), transform .18s var(--ds-ease-in-out), visibility 0s linear;flex:none;line-height:20px;overflow:hidden}.qDHVXG_sectionLabelHidden{opacity:0;visibility:hidden;max-width:0;margin-right:-4px;transition-delay:0s,0s,0s,0s,.18s;transform:translate(-4px)}.qDHVXG_searchSlot{box-sizing:border-box;min-width:0;max-width:28px;transition:max-width .18s var(--ds-ease-in-out), padding-left .18s var(--ds-ease-in-out);flex:1;align-items:center;margin-left:auto;padding-left:0;display:flex}.qDHVXG_searchSlotExpanded{max-width:100%;padding-left:0}.qDHVXG_headerActions{opacity:1;visibility:visible;max-width:60px;transition:max-width .18s var(--ds-ease-in-out), opacity .12s var(--ds-ease-in-out), transform .18s var(--ds-ease-in-out), visibility 0s linear;flex:none;align-items:center;gap:4px;display:flex;overflow:hidden}.qDHVXG_headerActionsHidden{opacity:0;visibility:hidden;pointer-events:none;max-width:0;transition-delay:0s,0s,0s,.18s;transform:translate(4px)}.qDHVXG_search{box-sizing:border-box;cursor:text;width:100%;height:28px;color:var(--dsw-alias-label-secondary);transition:width .18s var(--ds-ease-in-out), padding .18s var(--ds-ease-in-out), border-color .18s var(--ds-ease-in-out), background-color .18s var(--ds-ease-in-out);background:0 0;border:none;border-radius:50%;flex:none;align-items:center;gap:0;margin:0;padding:0;display:flex;overflow:hidden}.qDHVXG_searchExpanded{border:1px solid var(--dsw-alias-border-l2);width:calc(100% + 4px);height:30px;color:var(--dsw-alias-label-caption);background:0 0;border-radius:10px;margin-inline:-2px;padding:0 4px 0 0}.qDHVXG_searchButton{cursor:pointer;width:28px;height:28px;color:inherit;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.qDHVXG_searchExpanded .qDHVXG_searchButton{width:28px;height:30px}.qDHVXG_searchButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.qDHVXG_searchExpanded .qDHVXG_searchButton:hover{background:0 0}.qDHVXG_searchInput{opacity:0;pointer-events:none;width:0;min-width:0;color:var(--dsw-alias-label-primary);transition:opacity .12s var(--ds-ease-in-out);background:0 0;border:none;outline:none;flex:1;font-size:13px;line-height:18px}.qDHVXG_searchExpanded .qDHVXG_searchInput{opacity:1;pointer-events:auto;margin-left:-2px}.qDHVXG_searchInput::placeholder{color:var(--dsw-alias-label-tertiary)}.qDHVXG_clearButton{cursor:pointer;width:24px;height:24px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.qDHVXG_clearButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.qDHVXG_rail .qDHVXG_sectionHeader{justify-content:flex-start;gap:0;margin-bottom:12px;padding-left:0}.qDHVXG_rail .qDHVXG_headerActions{max-width:none}.qDHVXG_rail .qDHVXG_iconButton{width:36px;height:36px;color:var(--dsw-alias-label-primary)}.qDHVXG_rail .qDHVXG_search{background:0 0;border-color:#0000;gap:0;width:36px;height:36px;margin:0 0 12px;padding:0}.qDHVXG_rail .qDHVXG_searchButton{width:36px;height:36px;color:var(--dsw-alias-label-primary)}.qDHVXG_rail .qDHVXG_searchButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.qDHVXG_listArea{min-height:0;margin-left:-4px;margin-right:calc(-1 * var(--dsh-session-list-edge-inset));flex-direction:column;flex:1;padding-left:4px;display:flex;overflow:visible}.qDHVXG_rail .qDHVXG_listArea{margin-left:0;margin-right:0;padding-left:0}.qDHVXG_treeBody{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.qDHVXG_fade{left:0;right:var(--dsh-session-list-edge-inset);background:linear-gradient(to bottom, transparent, var(--dsw-specific-sidebar-fill));pointer-events:none;height:24px;position:absolute;bottom:0}.qDHVXG_wide{animation:qDHVXG_wide-in .2s var(--ds-ease-in-out)}@keyframes qDHVXG_wide-in{0%{opacity:0}}.qDHVXG_list{min-height:0;margin-left:-4px;margin-right:var(--dsh-session-list-scrollbar-offset);padding-left:4px;padding-right:calc(var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width) - var(--dsh-session-list-scrollbar-offset));scrollbar-gutter:stable;flex:1;padding-bottom:16px;overflow-y:auto}.qDHVXG_flatList>*+*,.qDHVXG_searchTree>[role=treeitem]+[role=treeitem],.qDHVXG_groupSection>*+*{margin-top:2px}.qDHVXG_searchStatus,.qDHVXG_searchWarning{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:12px;line-height:18px}.qDHVXG_searchWarning{color:var(--dsw-alias-label-secondary)}.qDHVXG_groupSection{position:relative}.qDHVXG_groupSection+.qDHVXG_groupSection{margin-top:4px}.qDHVXG_listTopDropIndicator,.qDHVXG_workspaceDropBefore:before,.qDHVXG_workspaceDropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:0}.qDHVXG_listTopDropIndicator{top:-8px;left:0;right:var(--dsh-session-list-edge-inset)}.qDHVXG_listTopDropActive>.qDHVXG_workspaceDropBefore:first-child:before{display:none}.qDHVXG_workspaceDropBefore:before{top:-8px}.qDHVXG_workspaceDropAfter:after{bottom:-8px}.qDHVXG_sessionOverflowButton{cursor:pointer;text-align:left;width:100%;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:8px;padding:0 12px 0 28px;font-size:12px}.qDHVXG_groupSection>.qDHVXG_sessionOverflowButton{margin-top:0}.qDHVXG_sessionOverflowButton:hover{color:var(--dsw-alias-label-secondary);background:0 0}.qDHVXG_empty{color:var(--dsw-alias-label-tertiary);padding:16px 12px;font-size:13px}.qDHVXG_renameInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;height:44px;color:var(--dsw-alias-label-primary);background:0 0;border-radius:22px;outline:none;padding:7px 14px;font-size:14px;font-weight:400;line-height:22px}.qDHVXG_renameInput:disabled{color:var(--dsw-alias-label-dimmed)}.qDHVXG_renameError{color:var(--dsw-alias-state-error-primary);margin-top:8px;font-size:12px;line-height:18px}.qDHVXG_deleteAction:not(:disabled){color:var(--dsw-alias-state-error-primary)}.qDHVXG_deleteStatus{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}@media (prefers-reduced-motion:reduce){.qDHVXG_wide{animation:none}.qDHVXG_search,.qDHVXG_sectionLabel,.qDHVXG_searchSlot,.qDHVXG_searchInput,.qDHVXG_headerActions{transition:none}}";
1186
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-workspace/src/client/rows/WorkspaceBrowser.module.css.mjs
1187
+ const css = ".bhn1Oq_root{--dsh-session-list-edge-inset:var(--dsh-sidebar-inline-padding);--dsh-session-list-scrollbar-width:8px;--dsh-session-list-scrollbar-offset:2px;box-sizing:border-box;min-height:0;padding-right:var(--dsh-session-list-edge-inset);flex-direction:column;flex:1;display:flex}.bhn1Oq_root.bhn1Oq_rail{padding-right:0}.bhn1Oq_iconButton{corner-shape:round;cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.bhn1Oq_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.bhn1Oq_sectionHeader{box-sizing:border-box;height:36px;color:var(--dsw-alias-label-tertiary);border-radius:12px;flex:none;justify-content:flex-end;align-items:center;gap:4px;margin-bottom:4px;padding-left:4px;display:flex;overflow:hidden}.bhn1Oq_root:not(.bhn1Oq_rail) .bhn1Oq_sectionHeader{margin-top:2px;margin-right:-4px}.bhn1Oq_sectionLabel{white-space:nowrap;opacity:1;visibility:visible;min-width:0;max-width:45%;transition:max-width .18s var(--ds-ease-in-out), margin-right .18s var(--ds-ease-in-out), opacity .12s var(--ds-ease-in-out), transform .18s var(--ds-ease-in-out), visibility 0s linear;flex:none;line-height:20px;overflow:hidden}.bhn1Oq_sectionLabelHidden{opacity:0;visibility:hidden;max-width:0;margin-right:-4px;transition-delay:0s,0s,0s,0s,.18s;transform:translate(-4px)}.bhn1Oq_searchSlot{box-sizing:border-box;min-width:0;max-width:28px;transition:max-width .18s var(--ds-ease-in-out), padding-left .18s var(--ds-ease-in-out);flex:1;align-items:center;margin-left:auto;padding-left:0;display:flex}.bhn1Oq_searchSlotExpanded{max-width:100%;padding-left:0}.bhn1Oq_headerActions{opacity:1;visibility:visible;max-width:60px;transition:max-width .18s var(--ds-ease-in-out), opacity .12s var(--ds-ease-in-out), transform .18s var(--ds-ease-in-out), visibility 0s linear;flex:none;align-items:center;gap:4px;display:flex;overflow:hidden}.bhn1Oq_headerActionsHidden{opacity:0;visibility:hidden;pointer-events:none;max-width:0;transition-delay:0s,0s,0s,.18s;transform:translate(4px)}.bhn1Oq_search{box-sizing:border-box;corner-shape:round;cursor:text;width:100%;height:28px;color:var(--dsw-alias-label-secondary);transition:width .18s var(--ds-ease-in-out), padding .18s var(--ds-ease-in-out), border-color .18s var(--ds-ease-in-out), background-color .18s var(--ds-ease-in-out);background:0 0;border:none;border-radius:50%;flex:none;align-items:center;gap:0;margin:0;padding:0;display:flex;overflow:hidden}.bhn1Oq_searchExpanded{border:.5px solid var(--dsw-alias-border-l4);width:calc(100% + 4px);height:30px;color:var(--dsw-alias-label-caption);background:0 0;border-radius:10px;margin-inline:-2px;padding:0 4px 0 0}.bhn1Oq_searchButton{corner-shape:round;cursor:pointer;width:28px;height:28px;color:inherit;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.bhn1Oq_searchExpanded .bhn1Oq_searchButton{width:28px;height:30px}.bhn1Oq_searchButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.bhn1Oq_searchExpanded .bhn1Oq_searchButton:hover{background:0 0}.bhn1Oq_searchInput{opacity:0;pointer-events:none;width:0;min-width:0;color:var(--dsw-alias-label-primary);transition:opacity .12s var(--ds-ease-in-out);background:0 0;border:none;outline:none;flex:1;font-size:13px;line-height:18px}.bhn1Oq_searchExpanded .bhn1Oq_searchInput{opacity:1;pointer-events:auto;margin-left:-2px}.bhn1Oq_searchInput::placeholder{color:var(--dsw-alias-label-tertiary)}.bhn1Oq_clearButton{corner-shape:round;cursor:pointer;width:24px;height:24px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.bhn1Oq_clearButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.bhn1Oq_rail .bhn1Oq_sectionHeader{justify-content:flex-start;gap:0;margin-bottom:12px;padding-left:0}.bhn1Oq_rail .bhn1Oq_headerActions{max-width:none}.bhn1Oq_rail .bhn1Oq_iconButton{width:36px;height:36px;color:var(--dsw-alias-label-primary)}.bhn1Oq_rail .bhn1Oq_search{background:0 0;border-color:#0000;gap:0;width:36px;height:36px;margin:0 0 12px;padding:0}.bhn1Oq_rail .bhn1Oq_searchButton{width:36px;height:36px;color:var(--dsw-alias-label-primary)}.bhn1Oq_rail .bhn1Oq_searchButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.bhn1Oq_listArea{min-height:0;margin-left:-4px;margin-right:calc(-1 * var(--dsh-session-list-edge-inset));flex-direction:column;flex:1;padding-left:4px;display:flex;overflow:visible}.bhn1Oq_rail .bhn1Oq_listArea{margin-left:0;margin-right:0;padding-left:0}.bhn1Oq_treeBody{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.bhn1Oq_fade{left:0;right:var(--dsh-session-list-edge-inset);background:linear-gradient(to bottom, transparent, var(--dsw-specific-sidebar-fill));pointer-events:none;height:24px;position:absolute;bottom:0}.bhn1Oq_wide{animation:bhn1Oq_wide-in .2s var(--ds-ease-in-out)}@keyframes bhn1Oq_wide-in{0%{opacity:0}}.bhn1Oq_list{min-height:0;margin-left:-4px;margin-right:var(--dsh-session-list-scrollbar-offset);padding-left:4px;padding-right:calc(var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width) - var(--dsh-session-list-scrollbar-offset));scrollbar-gutter:stable;flex:1;padding-bottom:16px;overflow-y:auto}.bhn1Oq_flatList>*+*,.bhn1Oq_searchTree>[role=treeitem]+[role=treeitem],.bhn1Oq_groupSection>*+*{margin-top:2px}.bhn1Oq_searchStatus,.bhn1Oq_searchWarning{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:12px;line-height:18px}.bhn1Oq_searchWarning{color:var(--dsw-alias-label-secondary)}.bhn1Oq_groupSection{position:relative}.bhn1Oq_groupSection+.bhn1Oq_groupSection{margin-top:4px}.bhn1Oq_listTopDropIndicator,.bhn1Oq_workspaceDropBefore:before,.bhn1Oq_workspaceDropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:0}.bhn1Oq_listTopDropIndicator{top:-8px;left:0;right:var(--dsh-session-list-edge-inset)}.bhn1Oq_listTopDropActive>.bhn1Oq_workspaceDropBefore:first-child:before{display:none}.bhn1Oq_workspaceDropBefore:before{top:-8px}.bhn1Oq_workspaceDropAfter:after{bottom:-8px}.bhn1Oq_sessionOverflowButton{cursor:pointer;text-align:left;width:100%;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:8px;padding:0 12px 0 28px;font-size:12px}.bhn1Oq_groupSection>.bhn1Oq_sessionOverflowButton{margin-top:0}.bhn1Oq_sessionOverflowButton:hover{color:var(--dsw-alias-label-secondary);background:0 0}.bhn1Oq_empty{color:var(--dsw-alias-label-tertiary);padding:16px 12px;font-size:13px}.bhn1Oq_renameInput{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:44px;color:var(--dsw-alias-label-primary);background:0 0;border-radius:22px;outline:none;padding:7px 14px;font-size:14px;font-weight:400;line-height:22px}.bhn1Oq_renameInput:disabled{color:var(--dsw-alias-label-dimmed)}.bhn1Oq_renameError{color:var(--dsw-alias-state-error-primary);margin-top:8px;font-size:12px;line-height:18px}.bhn1Oq_deleteAction:not(:disabled){color:var(--dsw-alias-state-error-primary)}.bhn1Oq_deleteStatus{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}@media (prefers-reduced-motion:reduce){.bhn1Oq_wide{animation:none}.bhn1Oq_search,.bhn1Oq_sectionLabel,.bhn1Oq_searchSlot,.bhn1Oq_searchInput,.bhn1Oq_headerActions{transition:none}}";
970
1188
  const tagId = "@deepseek-ai/dsh-client-ui-workspace/WorkspaceBrowser.module.css";
971
1189
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
972
1190
  const tag = document.createElement("style");
@@ -976,45 +1194,45 @@ window.__ModuleLoader__.load({
976
1194
  document.head.appendChild(tag);
977
1195
  }
978
1196
  var WorkspaceBrowser_module_css_default = {
979
- "clearButton": "qDHVXG_clearButton",
980
- "deleteAction": "qDHVXG_deleteAction",
981
- "deleteStatus": "qDHVXG_deleteStatus",
982
- "empty": "qDHVXG_empty",
983
- "fade": "qDHVXG_fade",
984
- "flatList": "qDHVXG_flatList",
985
- "groupSection": "qDHVXG_groupSection",
986
- "headerActions": "qDHVXG_headerActions",
987
- "headerActionsHidden": "qDHVXG_headerActionsHidden",
988
- "iconButton": "qDHVXG_iconButton",
989
- "list": "qDHVXG_list",
990
- "listArea": "qDHVXG_listArea",
991
- "listTopDropActive": "qDHVXG_listTopDropActive",
992
- "listTopDropIndicator": "qDHVXG_listTopDropIndicator",
993
- "rail": "qDHVXG_rail",
994
- "renameError": "qDHVXG_renameError",
995
- "renameInput": "qDHVXG_renameInput",
996
- "root": "qDHVXG_root",
997
- "search": "qDHVXG_search",
998
- "searchButton": "qDHVXG_searchButton",
999
- "searchExpanded": "qDHVXG_searchExpanded",
1000
- "searchInput": "qDHVXG_searchInput",
1001
- "searchSlot": "qDHVXG_searchSlot",
1002
- "searchSlotExpanded": "qDHVXG_searchSlotExpanded",
1003
- "searchStatus": "qDHVXG_searchStatus",
1004
- "searchTree": "qDHVXG_searchTree",
1005
- "searchWarning": "qDHVXG_searchWarning",
1006
- "sectionHeader": "qDHVXG_sectionHeader",
1007
- "sectionLabel": "qDHVXG_sectionLabel",
1008
- "sectionLabelHidden": "qDHVXG_sectionLabelHidden",
1009
- "sessionOverflowButton": "qDHVXG_sessionOverflowButton",
1010
- "treeBody": "qDHVXG_treeBody",
1011
- "wide": "qDHVXG_wide",
1012
- "wide-in": "qDHVXG_wide-in",
1013
- "workspaceDropAfter": "qDHVXG_workspaceDropAfter",
1014
- "workspaceDropBefore": "qDHVXG_workspaceDropBefore"
1197
+ "clearButton": "bhn1Oq_clearButton",
1198
+ "deleteAction": "bhn1Oq_deleteAction",
1199
+ "deleteStatus": "bhn1Oq_deleteStatus",
1200
+ "empty": "bhn1Oq_empty",
1201
+ "fade": "bhn1Oq_fade",
1202
+ "flatList": "bhn1Oq_flatList",
1203
+ "groupSection": "bhn1Oq_groupSection",
1204
+ "headerActions": "bhn1Oq_headerActions",
1205
+ "headerActionsHidden": "bhn1Oq_headerActionsHidden",
1206
+ "iconButton": "bhn1Oq_iconButton",
1207
+ "list": "bhn1Oq_list",
1208
+ "listArea": "bhn1Oq_listArea",
1209
+ "listTopDropActive": "bhn1Oq_listTopDropActive",
1210
+ "listTopDropIndicator": "bhn1Oq_listTopDropIndicator",
1211
+ "rail": "bhn1Oq_rail",
1212
+ "renameError": "bhn1Oq_renameError",
1213
+ "renameInput": "bhn1Oq_renameInput",
1214
+ "root": "bhn1Oq_root",
1215
+ "search": "bhn1Oq_search",
1216
+ "searchButton": "bhn1Oq_searchButton",
1217
+ "searchExpanded": "bhn1Oq_searchExpanded",
1218
+ "searchInput": "bhn1Oq_searchInput",
1219
+ "searchSlot": "bhn1Oq_searchSlot",
1220
+ "searchSlotExpanded": "bhn1Oq_searchSlotExpanded",
1221
+ "searchStatus": "bhn1Oq_searchStatus",
1222
+ "searchTree": "bhn1Oq_searchTree",
1223
+ "searchWarning": "bhn1Oq_searchWarning",
1224
+ "sectionHeader": "bhn1Oq_sectionHeader",
1225
+ "sectionLabel": "bhn1Oq_sectionLabel",
1226
+ "sectionLabelHidden": "bhn1Oq_sectionLabelHidden",
1227
+ "sessionOverflowButton": "bhn1Oq_sessionOverflowButton",
1228
+ "treeBody": "bhn1Oq_treeBody",
1229
+ "wide": "bhn1Oq_wide",
1230
+ "wide-in": "bhn1Oq_wide-in",
1231
+ "workspaceDropAfter": "bhn1Oq_workspaceDropAfter",
1232
+ "workspaceDropBefore": "bhn1Oq_workspaceDropBefore"
1015
1233
  };
1016
1234
  //#endregion
1017
- //#region lib/types/client/WorkspaceBrowser.js
1235
+ //#region lib/types/client/rows/WorkspaceBrowser.js
1018
1236
  /**
1019
1237
  * The workspace/session browsing region filling the sidebar shell's
1020
1238
  * `sidebar.workspaces` hole: section header (title + view options + add
@@ -1037,6 +1255,20 @@ window.__ModuleLoader__.load({
1037
1255
  const SEARCH_QUERY_MAX_CODE_UNITS = 500;
1038
1256
  /** Session rows visible per Workspace before the local overflow control. */
1039
1257
  const COLLAPSED_SESSION_LIMIT = 5;
1258
+ /** Fold one Workspace without charging its provisional New Session against the ordinary-row limit. */
1259
+ function collapsedSessionRows(sessions) {
1260
+ let ordinaryCount = 0;
1261
+ const rows = sessions.filter((session) => {
1262
+ if (session.blank) return true;
1263
+ if (ordinaryCount >= COLLAPSED_SESSION_LIMIT) return false;
1264
+ ordinaryCount += 1;
1265
+ return true;
1266
+ });
1267
+ return {
1268
+ rows,
1269
+ hiddenCount: sessions.length - rows.length
1270
+ };
1271
+ }
1040
1272
  /** Keep controlled input and RPC payload inside the session.search wire contract. */
1041
1273
  function sanitizeSearchQuery(value) {
1042
1274
  const withoutNul = value.replaceAll("\0", "");
@@ -1197,8 +1429,9 @@ window.__ModuleLoader__.load({
1197
1429
  return e.clientY < rect.top + rect.height / 2 ? "before" : "after";
1198
1430
  }
1199
1431
  /** The scrolling session tree; unmounting drops the sessions subscription and expand-all state. */
1200
- function SessionTree({ useSessions, startSession, open, forkSession, workspaces, archivedSessionIds, onRenameRequest, onDeleteRequest, onSessionRename, onSessionArchive, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, home, t }) {
1432
+ function SessionTree({ useSessions, useSessionPendingInteraction, startSession, open, forkSession, workspaces, archivedSessionIds, onRenameRequest, onDeleteRequest, onSessionRename, onSessionArchive, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, home, t }) {
1201
1433
  const list = useSessions((s) => s);
1434
+ const pendingInteractions = useSessionPendingInteraction((s) => s);
1202
1435
  const current = list.current;
1203
1436
  const [expandedSessionGroups, setExpandedSessionGroups] = (0, react.useState)([]);
1204
1437
  const [drag, setDrag] = (0, react.useState)(null);
@@ -1265,13 +1498,14 @@ window.__ModuleLoader__.load({
1265
1498
  });
1266
1499
  }, [sessionOrderByAccount, workspaces]);
1267
1500
  const orderedUngroupedSessionIds = (0, react.useMemo)(() => reconciledSessionOrder(ungroupedSessionIds, sessionOrderByAccount[""]), [sessionOrderByAccount, ungroupedSessionIds]);
1268
- const groups = (0, react.useMemo)(() => deriveGroups(list, orderedWorkspaces, archivedSessionIds, {
1501
+ const groups = (0, react.useMemo)(() => deriveGroups(list, orderedWorkspaces, archivedSessionIds, pendingInteractions, {
1269
1502
  expandedGroups,
1270
1503
  ...sessionOrderByAccount[""] === void 0 ? {} : { ungroupedOrder: sessionOrderByAccount[""] }
1271
1504
  }), [
1272
1505
  list,
1273
1506
  orderedWorkspaces,
1274
1507
  archivedSessionIds,
1508
+ pendingInteractions,
1275
1509
  expandedGroups,
1276
1510
  sessionOrderByAccount
1277
1511
  ]);
@@ -1282,18 +1516,40 @@ window.__ModuleLoader__.load({
1282
1516
  setDrag(null);
1283
1517
  const group = groups.find((candidate) => candidate.key === activeDrag.accountKey);
1284
1518
  if (group === void 0) return;
1285
- const targetIndex = group.sessions.findIndex((session) => session.id === over.id);
1519
+ const sessionsExpanded = expandedSessionGroups.includes(group.key);
1520
+ const renderedSessions = sessionsExpanded ? group.sessions : collapsedSessionRows(group.sessions).rows;
1521
+ const targetIndex = renderedSessions.findIndex((session) => session.id === over.id);
1286
1522
  if (targetIndex === -1) return;
1287
- const anchor = over.half === "before" ? over.id : group.sessions[targetIndex + 1]?.id;
1288
- if (anchor === activeDrag.sessionId) return;
1289
- const sourceIndex = group.sessions.findIndex((session) => session.id === activeDrag.sessionId);
1290
- const anchorIndex = anchor === void 0 ? group.sessions.length : group.sessions.findIndex((session) => session.id === anchor);
1291
- if (sourceIndex !== -1 && (anchorIndex === sourceIndex || anchorIndex === sourceIndex + 1)) return;
1523
+ const sourceIndex = renderedSessions.findIndex((session) => session.id === activeDrag.sessionId);
1524
+ if (over.id === activeDrag.sessionId) return;
1525
+ const withoutSource = renderedSessions.filter((session) => session.id !== activeDrag.sessionId);
1526
+ const targetWithoutSourceIndex = withoutSource.findIndex((session) => session.id === over.id);
1527
+ if (targetWithoutSourceIndex === -1) return;
1528
+ const visibleInsertAt = over.half === "before" ? targetWithoutSourceIndex : targetWithoutSourceIndex + 1;
1529
+ if (sourceIndex !== -1 && visibleInsertAt === sourceIndex) return;
1292
1530
  const accountSessionIds = activeDrag.accountKey === "" ? orderedUngroupedSessionIds : orderedWorkspaces.find((workspace) => workspace.workspaceId === activeDrag.accountKey)?.sessionIds;
1293
1531
  if (accountSessionIds === void 0) return;
1294
1532
  const nextOrder = accountSessionIds.filter((id) => id !== activeDrag.sessionId);
1533
+ let anchor;
1534
+ if (sessionsExpanded) anchor = over.half === "before" ? over.id : renderedSessions[targetIndex + 1]?.id;
1535
+ else {
1536
+ const previousVisible = withoutSource[visibleInsertAt - 1]?.id;
1537
+ if (previousVisible === void 0) anchor = nextOrder[0];
1538
+ else {
1539
+ const previousIndex = nextOrder.indexOf(previousVisible);
1540
+ if (previousIndex === -1) return;
1541
+ anchor = nextOrder[previousIndex + 1];
1542
+ }
1543
+ }
1295
1544
  const insertAt = anchor === void 0 ? nextOrder.length : nextOrder.indexOf(anchor);
1296
1545
  nextOrder.splice(insertAt === -1 ? nextOrder.length : insertAt, 0, activeDrag.sessionId);
1546
+ if (!sessionsExpanded && sourceIndex !== -1) {
1547
+ const nodes = new Map(group.sessions.map((node) => [node.id, node]));
1548
+ if (!collapsedSessionRows(nextOrder.flatMap((id) => {
1549
+ const node = nodes.get(id);
1550
+ return node === void 0 ? [] : [node];
1551
+ })).rows.some((node) => node.id === activeDrag.sessionId)) return;
1552
+ }
1297
1553
  setSessionOrder(activeDrag.accountKey, nextOrder.map((id) => id));
1298
1554
  if (orderBy === "updated" || activeDrag.accountKey === "") return;
1299
1555
  insertSessionBefore(activeDrag.accountKey, activeDrag.sessionId, anchor).catch((reason) => {
@@ -1332,6 +1588,8 @@ window.__ModuleLoader__.load({
1332
1588
  children: t("empty.none")
1333
1589
  }), groups.map((group) => {
1334
1590
  const workspaceId = group.workspaceId;
1591
+ const collapsed = collapsedSessionRows(group.sessions);
1592
+ const sessionsExpanded = expandedSessionGroups.includes(group.key);
1335
1593
  const workspaceMarker = workspaceId !== void 0 && workspaceDrag?.over?.id === workspaceId ? workspaceDrag.over.half : null;
1336
1594
  const workspaceDragProps = workspaceId === void 0 ? void 0 : {
1337
1595
  start: () => {
@@ -1401,7 +1659,7 @@ window.__ModuleLoader__.load({
1401
1659
  }
1402
1660
  }
1403
1661
  }),
1404
- (expandedSessionGroups.includes(group.key) ? group.sessions : group.sessions.slice(0, COLLAPSED_SESSION_LIMIT)).map((node) => {
1662
+ (sessionsExpanded ? group.sessions : collapsed.rows).map((node) => {
1405
1663
  const sameGroupDrag = drag !== null && drag.accountKey === group.key;
1406
1664
  return (0, react_jsx_runtime.jsx)(SessionNodeItem, {
1407
1665
  node,
@@ -1449,14 +1707,14 @@ window.__ModuleLoader__.load({
1449
1707
  t
1450
1708
  }, node.id);
1451
1709
  }),
1452
- group.sessions.length > COLLAPSED_SESSION_LIMIT && (0, react_jsx_runtime.jsx)("button", {
1710
+ collapsed.hiddenCount > 0 && (0, react_jsx_runtime.jsx)("button", {
1453
1711
  type: "button",
1454
1712
  className: WorkspaceBrowser_module_css_default.sessionOverflowButton,
1455
- "aria-expanded": expandedSessionGroups.includes(group.key),
1713
+ "aria-expanded": sessionsExpanded,
1456
1714
  onClick: () => {
1457
1715
  setExpandedSessionGroups((keys) => toggled(keys, group.key));
1458
1716
  },
1459
- children: expandedSessionGroups.includes(group.key) ? t("sessions.collapse") : t("sessions.expand", { n: group.sessions.length - COLLAPSED_SESSION_LIMIT })
1717
+ children: sessionsExpanded ? t("sessions.collapse") : t("sessions.expand", { n: collapsed.hiddenCount })
1460
1718
  })
1461
1719
  ]
1462
1720
  }, group.key);
@@ -1467,9 +1725,14 @@ window.__ModuleLoader__.load({
1467
1725
  });
1468
1726
  }
1469
1727
  /** The flat "In one list" body: every session is one draggable top-level row. */
1470
- function FlatList({ useSessions, open, forkSession, onSessionRename, onSessionArchive, archivedSessionIds, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, t }) {
1728
+ function FlatList({ useSessions, useSessionPendingInteraction, open, forkSession, onSessionRename, onSessionArchive, archivedSessionIds, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, t }) {
1471
1729
  const list = useSessions((s) => s);
1472
- const baseRows = (0, react.useMemo)(() => deriveFlat(list, archivedSessionIds), [list, archivedSessionIds]);
1730
+ const pendingInteractions = useSessionPendingInteraction((s) => s);
1731
+ const baseRows = (0, react.useMemo)(() => deriveFlat(list, archivedSessionIds, pendingInteractions), [
1732
+ list,
1733
+ archivedSessionIds,
1734
+ pendingInteractions
1735
+ ]);
1473
1736
  const sessionIds = (0, react.useMemo)(() => baseRows.map((row) => row.id), [baseRows]);
1474
1737
  const previousOrderBy = (0, react.useRef)(orderBy);
1475
1738
  (0, react.useEffect)(() => {
@@ -1585,19 +1848,21 @@ window.__ModuleLoader__.load({
1585
1848
  });
1586
1849
  }
1587
1850
  /** Flat search body: local metadata matches plus the current Host result page. */
1588
- function SearchResults({ useSessions, open, workspaces, archivedSessionIds, query, remote, resultLimit, t }) {
1851
+ function SearchResults({ useSessions, useSessionPendingInteraction, open, workspaces, archivedSessionIds, query, remote, resultLimit, t }) {
1589
1852
  const list = useSessions((s) => s);
1853
+ const pendingInteractions = useSessionPendingInteraction((s) => s);
1590
1854
  const currentRemote = remote.query === query ? remote : {
1591
1855
  query,
1592
1856
  status: "loading",
1593
1857
  items: [],
1594
1858
  hasMore: false
1595
1859
  };
1596
- const results = (0, react.useMemo)(() => deriveSearchResults(list, workspaces, query, archivedSessionIds, currentRemote, resultLimit), [
1860
+ const results = (0, react.useMemo)(() => deriveSearchResults(list, workspaces, query, archivedSessionIds, pendingInteractions, currentRemote, resultLimit), [
1597
1861
  list,
1598
1862
  workspaces,
1599
1863
  query,
1600
1864
  archivedSessionIds,
1865
+ pendingInteractions,
1601
1866
  currentRemote,
1602
1867
  resultLimit
1603
1868
  ]);
@@ -1646,8 +1911,8 @@ window.__ModuleLoader__.load({
1646
1911
  * @param props - composed slot props (shell owner share + store + injected actions).
1647
1912
  * @returns the region element tree.
1648
1913
  */
1649
- function WorkspaceBrowser({ wide, expandSidebar, useSessions, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostDescription, renderSlot, t }) {
1650
- const home = useHostDescription((description) => description?.home);
1914
+ function WorkspaceBrowser({ wide, expandSidebar, useSessions, useSessionPendingInteraction, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, renderSlot, t }) {
1915
+ const home = useHostInfo((info) => info.home);
1651
1916
  const workspaces = useWorkspaces((state) => state.items);
1652
1917
  const workspacePhase = useWorkspaces((state) => state.phase);
1653
1918
  const archivedSessionIds = useWorkspaces((state) => state.archivedSessionIds);
@@ -1668,7 +1933,8 @@ window.__ModuleLoader__.load({
1668
1933
  promotedBlank.current = void 0;
1669
1934
  return;
1670
1935
  }
1671
- if (promotedBlank.current?.sessionId === currentBlankSessionId && promotedBlank.current.accountKey === currentBlankAccount) return;
1936
+ const promoted = promotedBlank.current;
1937
+ if (promoted !== void 0 && promoted.sessionId === currentBlankSessionId && promoted.accountKey === currentBlankAccount) return;
1672
1938
  promotedBlank.current = {
1673
1939
  sessionId: currentBlankSessionId,
1674
1940
  accountKey: currentBlankAccount
@@ -2014,6 +2280,7 @@ window.__ModuleLoader__.load({
2014
2280
  className: WorkspaceBrowser_module_css_default.listArea,
2015
2281
  children: wide && (normalizedQuery !== "" ? (0, react_jsx_runtime.jsx)(SearchResults, {
2016
2282
  useSessions,
2283
+ useSessionPendingInteraction,
2017
2284
  open,
2018
2285
  workspaces,
2019
2286
  archivedSessionIds,
@@ -2023,6 +2290,7 @@ window.__ModuleLoader__.load({
2023
2290
  t
2024
2291
  }) : groupBy === "flat" ? (0, react_jsx_runtime.jsx)(FlatList, {
2025
2292
  useSessions,
2293
+ useSessionPendingInteraction,
2026
2294
  open,
2027
2295
  forkSession,
2028
2296
  onSessionRename,
@@ -2036,6 +2304,7 @@ window.__ModuleLoader__.load({
2036
2304
  t
2037
2305
  }) : (0, react_jsx_runtime.jsx)(SessionTree, {
2038
2306
  useSessions,
2307
+ useSessionPendingInteraction,
2039
2308
  onSessionRename,
2040
2309
  onSessionArchive,
2041
2310
  forkSession,
@@ -2265,6 +2534,7 @@ window.__ModuleLoader__.load({
2265
2534
  "status.planReview": "计划待审",
2266
2535
  "status.waitingAnswer": "等待回答",
2267
2536
  "status.completed": "已完成",
2537
+ "schedule.active": "有活动定时任务",
2268
2538
  "hover.created": "创建于 {time}",
2269
2539
  "hover.copied": "已复制",
2270
2540
  "date.ymd": "{y}年{m}月{d}日",
@@ -2330,6 +2600,7 @@ window.__ModuleLoader__.load({
2330
2600
  "status.planReview": "Plan awaiting review",
2331
2601
  "status.waitingAnswer": "Waiting for answer",
2332
2602
  "status.completed": "Completed",
2603
+ "schedule.active": "Has active scheduled task",
2333
2604
  "hover.created": "Created {time}",
2334
2605
  "hover.copied": "Copied",
2335
2606
  "date.ymd": "{y}-{m}-{d}",
@@ -2358,7 +2629,8 @@ window.__ModuleLoader__.load({
2358
2629
  "sessions",
2359
2630
  "workspaces",
2360
2631
  "locale",
2361
- "connection"
2632
+ "remote",
2633
+ "remote.directoryPicker"
2362
2634
  ];
2363
2635
  /**
2364
2636
  * Register the browser and picker once their slot declarations are on the
@@ -2367,13 +2639,16 @@ window.__ModuleLoader__.load({
2367
2639
  * @param ctx - client root context.
2368
2640
  */
2369
2641
  function apply(ctx) {
2370
- const hostDescription = ctx.get("connection").hostDescription;
2642
+ const sessions = ctx.get("sessions");
2643
+ const workspaces = ctx.get("workspaces");
2644
+ const uiWorkspace = new UiWorkspaceService(ctx, ctx.remote.directoryPicker, workspaces, sessions);
2645
+ ctx.slots.provideRoot({ hooks: { workspaces: workspaces.list } });
2371
2646
  ctx.effect(() => ctx.locale.register(NS, {
2372
2647
  zh,
2373
2648
  en
2374
2649
  }), "ui-workspace: dictionaries");
2375
2650
  const searchSessions = async (query, signal) => {
2376
- const result = await ctx.sessions.search(query, signal);
2651
+ const result = await sessions.search(query, signal);
2377
2652
  if (!result.ok) throw new Error(result.error.message);
2378
2653
  return result.value;
2379
2654
  };
@@ -2382,53 +2657,57 @@ window.__ModuleLoader__.load({
2382
2657
  subscribe: (listener) => ctx.slots.subscribe(hole, listener)
2383
2658
  });
2384
2659
  const browserFlowSource = flowSource("sidebar.workspaces.directoryFlow");
2660
+ const hostInfo = {
2661
+ getSnapshot: () => ctx.remote.$host,
2662
+ subscribe: (listener) => ctx.on("connection/reset", listener)
2663
+ };
2385
2664
  const pickerFlowSource = flowSource("conversation.hero.workspace.directoryFlow");
2386
2665
  const browserInjected = () => ({
2387
2666
  startSession: (workspaceId) => {
2388
- ctx.workspaces.startSession(workspaceId);
2667
+ uiWorkspace.startSession(workspaceId);
2389
2668
  },
2390
2669
  open: (sessionId) => {
2391
- ctx.sessions.open(sessionId);
2670
+ sessions.open(sessionId);
2392
2671
  },
2393
2672
  searchSessions,
2394
- searchResultLimit: ctx.sessions.searchResultLimit,
2673
+ searchResultLimit: sessions.searchResultLimit,
2395
2674
  renameSession: async (sessionId, title) => {
2396
- const session = ctx.sessions.binding(sessionId)?.session;
2675
+ const session = sessions.binding(sessionId)?.session;
2397
2676
  if (session === void 0) throw new Error(`unknown session "${sessionId}"`);
2398
2677
  const result = await session.rename(title);
2399
2678
  if (!result.ok) throw new Error(result.error.message);
2400
2679
  },
2401
2680
  forkSession: (sessionId) => {
2402
- ctx.sessions.fork({
2681
+ sessions.fork({
2403
2682
  sessionId,
2404
2683
  increaseTitle: true
2405
2684
  }).then((childId) => {
2406
- ctx.sessions.open(childId);
2685
+ sessions.open(childId);
2407
2686
  }).catch(() => {});
2408
2687
  },
2409
2688
  renameWorkspace: async (workspaceId, title) => {
2410
- await ctx.workspaces.rename(workspaceId, title);
2689
+ await workspaces.rename(workspaceId, title);
2411
2690
  },
2412
2691
  deleteWorkspace: async (workspaceId) => {
2413
- await ctx.workspaces.delete(workspaceId);
2692
+ await workspaces.delete(workspaceId);
2414
2693
  },
2415
2694
  insertWorkspaceBefore: async (workspaceId, beforeWorkspaceId) => {
2416
- await ctx.workspaces.insertBefore(workspaceId, beforeWorkspaceId);
2695
+ await workspaces.insertBefore(workspaceId, beforeWorkspaceId);
2417
2696
  },
2418
2697
  archiveSession: async (sessionId) => {
2419
- await ctx.workspaces.archiveSession(sessionId);
2698
+ await uiWorkspace.archiveSession(sessionId);
2420
2699
  },
2421
2700
  insertSessionBefore: async (workspaceId, sessionId, beforeSessionId) => {
2422
- await ctx.workspaces.insertSessionBefore(workspaceId, sessionId, beforeSessionId);
2701
+ await workspaces.insertSessionBefore(workspaceId, sessionId, beforeSessionId);
2423
2702
  },
2424
- createWorkspace: (input) => ctx.workspaces.create(input),
2703
+ createWorkspace: (input) => workspaces.create(input),
2425
2704
  hooks: {
2426
2705
  directoryFlow: browserFlowSource,
2427
- hostDescription
2706
+ hostInfo
2428
2707
  }
2429
2708
  });
2430
2709
  const pickerInjected = () => ({
2431
- createWorkspace: (input) => ctx.workspaces.create(input),
2710
+ createWorkspace: (input) => workspaces.create(input),
2432
2711
  hooks: { directoryFlow: pickerFlowSource }
2433
2712
  });
2434
2713
  ctx.slots.inject("sidebar.workspaces", () => ctx.slots.register({