dsh-git-worktree 0.10.0 → 0.12.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 (78) hide show
  1. package/CHANGELOG.md +61 -1
  2. package/README.en.md +27 -17
  3. package/README.md +27 -17
  4. package/lib/adapters/git.js +45 -8
  5. package/lib/adapters/git.js.map +1 -1
  6. package/lib/adapters/project-skill-io.js +7 -1
  7. package/lib/adapters/project-skill-io.js.map +1 -1
  8. package/lib/adapters/project-skill-snapshot.d.ts +10 -0
  9. package/lib/adapters/project-skill-snapshot.js +182 -0
  10. package/lib/adapters/project-skill-snapshot.js.map +1 -0
  11. package/lib/adapters/project-skills.d.ts +18 -3
  12. package/lib/adapters/project-skills.js +102 -13
  13. package/lib/adapters/project-skills.js.map +1 -1
  14. package/lib/adapters/registry.js +4 -32
  15. package/lib/adapters/registry.js.map +1 -1
  16. package/lib/client/WorktreeCreateRow.js +14 -2
  17. package/lib/client/WorktreeCreateRow.js.map +1 -1
  18. package/lib/client/actions.d.ts +34 -1
  19. package/lib/client/actions.js +41 -0
  20. package/lib/client/actions.js.map +1 -1
  21. package/lib/client/index.d.ts +6 -1
  22. package/lib/client/index.js +11 -2
  23. package/lib/client/index.js.map +1 -1
  24. package/lib/client/pre-session/controller.js +5 -0
  25. package/lib/client/pre-session/controller.js.map +1 -1
  26. package/lib/client/review-console/PreflightStatus.js +5 -2
  27. package/lib/client/review-console/PreflightStatus.js.map +1 -1
  28. package/lib/client/review-console/ReviewActions.js +47 -46
  29. package/lib/client/review-console/ReviewActions.js.map +1 -1
  30. package/lib/client/review-console/ReviewDetailsModal.js +13 -3
  31. package/lib/client/review-console/ReviewDetailsModal.js.map +1 -1
  32. package/lib/client/review-console/review-console.styles.js +22 -11
  33. package/lib/client/review-console/review-console.styles.js.map +1 -1
  34. package/lib/client/target-console/TargetStatusAction.js +11 -9
  35. package/lib/client/target-console/TargetStatusAction.js.map +1 -1
  36. package/lib/client/target-console/WorktreeReviewStatus.js +7 -7
  37. package/lib/client/target-console/WorktreeReviewStatus.js.map +1 -1
  38. package/lib/client/workspace-desktop.d.ts +15 -0
  39. package/lib/client/workspace-desktop.js +95 -0
  40. package/lib/client/workspace-desktop.js.map +1 -0
  41. package/lib/client/workspace-sidebar/index.js +6 -3
  42. package/lib/client/workspace-sidebar/index.js.map +1 -1
  43. package/lib/client.js +1598 -454
  44. package/lib/commit-message.d.ts +2 -0
  45. package/lib/commit-message.js +5 -0
  46. package/lib/commit-message.js.map +1 -0
  47. package/lib/console-host/control-plane.js +6 -5
  48. package/lib/console-host/control-plane.js.map +1 -1
  49. package/lib/console-host/review-diff.js +9 -4
  50. package/lib/console-host/review-diff.js.map +1 -1
  51. package/lib/console-remote/schemas.d.ts +1 -1
  52. package/lib/console-remote/schemas.js +2 -1
  53. package/lib/console-remote/schemas.js.map +1 -1
  54. package/lib/creation-failure.d.ts +6 -0
  55. package/lib/creation-failure.js +9 -0
  56. package/lib/creation-failure.js.map +1 -1
  57. package/lib/host-compat.js +2 -1
  58. package/lib/host-compat.js.map +1 -1
  59. package/lib/i18n/client-messages.d.ts +16 -4
  60. package/lib/i18n/client-messages.js +5 -5
  61. package/lib/i18n/client-messages.js.map +1 -1
  62. package/lib/i18n/host-messages.d.ts +3 -7
  63. package/lib/i18n/host-messages.js +3 -7
  64. package/lib/i18n/host-messages.js.map +1 -1
  65. package/lib/index.d.ts +9 -9
  66. package/lib/ports.d.ts +1 -1
  67. package/lib/session-checkout-apply.js +12 -8
  68. package/lib/session-checkout-apply.js.map +1 -1
  69. package/lib/session-checkout-module.js +16 -8
  70. package/lib/session-checkout-module.js.map +1 -1
  71. package/lib/workspace-provider-lifecycle.js +31 -6
  72. package/lib/workspace-provider-lifecycle.js.map +1 -1
  73. package/package.json +43 -41
  74. package/scripts/check-publish.mjs +2 -0
  75. package/scripts/workspace-sidebar-resources.mjs +25 -0
  76. package/scripts/workspace-sidebar-upstream-alpha.mjs +18 -15
  77. package/scripts/workspace-sidebar-upstream-next.mjs +14 -17
  78. package/scripts/workspace-sidebar-upstream.mjs +20 -5
package/lib/client.js CHANGED
@@ -136,6 +136,14 @@ const clientMessages = {
136
136
  "zh": "未提供验证记录。",
137
137
  "en": "No validation records provided."
138
138
  },
139
+ "detail.expandList": {
140
+ "zh": "展开全部 {count} 项",
141
+ "en": "Show all {count} items"
142
+ },
143
+ "detail.collapseList": {
144
+ "zh": "收起",
145
+ "en": "Show fewer"
146
+ },
139
147
  "detail.version": {
140
148
  "zh": "版本信息",
141
149
  "en": "Version information"
@@ -188,10 +196,6 @@ const clientMessages = {
188
196
  "zh": "当前会话已切换,已停止准备独立工作目录。",
189
197
  "en": "The current session changed. Isolated working directory preparation stopped."
190
198
  },
191
- "500": {
192
- "zh": "/500",
193
- "en": "/500"
194
- },
195
199
  "the.cwd.of.new.harness.session.does.not": {
196
200
  "zh": "Harness 新建 Session {p0} 的 cwd 与 Host 记录不一致。",
197
201
  "en": "The cwd of new Harness Session {p0} does not match the Host record."
@@ -1723,6 +1727,14 @@ const clientMessages = {
1723
1727
  "error.category.invalid": {
1724
1728
  "zh": "无效请求",
1725
1729
  "en": "Invalid request"
1730
+ },
1731
+ "open.workspace.path.failed": {
1732
+ "zh": "无法打开该工作目录:{p0}",
1733
+ "en": "Could not open this working directory: {p0}"
1734
+ },
1735
+ "open.workspace.path.unavailable": {
1736
+ "zh": "当前 Host 未提供打开工作目录的能力。",
1737
+ "en": "This Host does not provide a desktop opener for working directories."
1726
1738
  }
1727
1739
  };
1728
1740
 
@@ -6185,6 +6197,13 @@ function superRefine(fn, params) {
6185
6197
  const describe = describe$1;
6186
6198
  const meta = meta$1;
6187
6199
 
6200
+ //#endregion
6201
+ //#region src/commit-message.ts
6202
+ /** Commit bodies are sent to Git on stdin; 500 characters is not a Git limit. */
6203
+ function isValidCommitMessage(value) {
6204
+ return typeof value === "string" && value.trim().length > 0 && !value.includes("\0");
6205
+ }
6206
+
6188
6207
  //#endregion
6189
6208
  //#region src/types.ts
6190
6209
  const SESSION_CHECKOUT_ERROR_CODES = [
@@ -6414,7 +6433,7 @@ const strict = (shape) => object(shape).strict();
6414
6433
  const sessionIdSchema = string().min(1).max(200).refine((value) => !/[\0\r\n]/u.test(value), "unsafe session id");
6415
6434
  const checkoutIdSchema = string().min(1).max(200).refine((value) => !value.includes("..") && !/[\\/\0\r\n]/u.test(value), "unsafe checkout id");
6416
6435
  const reviewIdSchema = string().min(1).max(200).refine((value) => !/[\0\r\n]/u.test(value), "unsafe review id");
6417
- const commitMessageSchema = string().trim().min(1).max(500);
6436
+ const commitMessageSchema = string().trim().refine(isValidCommitMessage, "invalid commit message");
6418
6437
  const revisionSchema = number().int().nonnegative();
6419
6438
  const gitOidSchema = string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/iu);
6420
6439
  const oidSchema = union([
@@ -8173,6 +8192,33 @@ function prefillSessionDraft(services, sessionId, text) {
8173
8192
  services.conversation.input.for(binding.ctx).setDraft(text);
8174
8193
  return true;
8175
8194
  }
8195
+ /** Only a successful Host answer is definitive; transport/provider failures are unknown. */
8196
+ async function readHostDesktopCapability(services) {
8197
+ try {
8198
+ const session = services.remote?.session;
8199
+ if (typeof session?.canOpenWorkspacePath !== "function") return void 0;
8200
+ const result = await session.canOpenWorkspacePath();
8201
+ return result.ok ? result.value === true : void 0;
8202
+ } catch {
8203
+ return;
8204
+ }
8205
+ }
8206
+ /**
8207
+ * Hand one verified managed root to the Host desktop.
8208
+ * Resolves the already-localized failure copy, or null once the Host
8209
+ * acknowledged the handoff; the caller owns where that copy becomes visible.
8210
+ */
8211
+ async function openHostPath(services, path) {
8212
+ const t = translatorForServices(services);
8213
+ const session = services.remote?.session;
8214
+ if (typeof session?.openWorkspacePath !== "function") return t("open.workspace.path.unavailable");
8215
+ try {
8216
+ const result = await session.openWorkspacePath({ path });
8217
+ return result.ok ? null : t("open.workspace.path.failed", { p0: result.error.message });
8218
+ } catch (reason) {
8219
+ return t("open.workspace.path.failed", { p0: reason instanceof Error ? reason.message : String(reason) });
8220
+ }
8221
+ }
8176
8222
 
8177
8223
  //#endregion
8178
8224
  //#region src/client/model.ts
@@ -8299,15 +8345,112 @@ function parseReviewTool(block, t = defaultClientTranslator) {
8299
8345
  };
8300
8346
  }
8301
8347
 
8348
+ //#endregion
8349
+ //#region src/client/workspace-desktop.tsx
8350
+ const availability = /* @__PURE__ */ new WeakMap();
8351
+ function entryFor$2(remote) {
8352
+ let entry = availability.get(remote);
8353
+ if (!entry) {
8354
+ entry = {
8355
+ attempts: 0,
8356
+ retryAt: 0,
8357
+ listeners: /* @__PURE__ */ new Set()
8358
+ };
8359
+ availability.set(remote, entry);
8360
+ }
8361
+ return entry;
8362
+ }
8363
+ function readAvailability(remote, entry) {
8364
+ if (entry.value !== void 0 || entry.pending || entry.timer !== void 0) return;
8365
+ if (entry.attempts >= 3) {
8366
+ if (Date.now() < entry.retryAt) return;
8367
+ entry.attempts = 0;
8368
+ }
8369
+ if (Date.now() < entry.retryAt) {
8370
+ if (entry.listeners.size) entry.timer = setTimeout(() => {
8371
+ entry.timer = void 0;
8372
+ readAvailability(remote, entry);
8373
+ }, entry.retryAt - Date.now());
8374
+ return;
8375
+ }
8376
+ entry.attempts += 1;
8377
+ entry.pending = readHostDesktopCapability({ remote }).then((value) => {
8378
+ entry.pending = void 0;
8379
+ if (value !== void 0) {
8380
+ entry.value = value;
8381
+ for (const listener of entry.listeners) listener();
8382
+ } else {
8383
+ entry.retryAt = Date.now() + (entry.attempts >= 3 ? 3e4 : entry.attempts * 1e3);
8384
+ if (entry.attempts < 3 && entry.listeners.size) readAvailability(remote, entry);
8385
+ }
8386
+ });
8387
+ }
8388
+ /** Warm the shared read without owning background retry timers. */
8389
+ function prefetchHostDesktop(remote) {
8390
+ if (remote !== void 0) readAvailability(remote, entryFor$2(remote));
8391
+ }
8392
+ /** undefined while pending/unavailable transport; false only for a successful no-desktop answer. */
8393
+ function useHostDesktopAvailable(remote) {
8394
+ const [, update] = (0, react.useState)(0);
8395
+ (0, react.useEffect)(() => {
8396
+ if (remote === void 0) return;
8397
+ const entry = entryFor$2(remote);
8398
+ const listener = () => update((value) => value + 1);
8399
+ entry.listeners.add(listener);
8400
+ readAvailability(remote, entry);
8401
+ return () => {
8402
+ entry.listeners.delete(listener);
8403
+ if (!entry.listeners.size && entry.timer !== void 0) {
8404
+ clearTimeout(entry.timer);
8405
+ entry.timer = void 0;
8406
+ }
8407
+ };
8408
+ }, [remote]);
8409
+ return remote === void 0 ? false : entryFor$2(remote).value;
8410
+ }
8411
+ /**
8412
+ * Transient failure banner owned by the gesture's control.
8413
+ * Menu rows close before the request settles, so an inline error inside the
8414
+ * menu would never be seen; the banner is announced from the control instead.
8415
+ */
8416
+ function useOpenFailureToast() {
8417
+ const seq = (0, react.useRef)(0);
8418
+ const [banner, setBanner] = (0, react.useState)(null);
8419
+ const dismiss = (0, react.useCallback)(() => {
8420
+ setBanner(null);
8421
+ }, []);
8422
+ return {
8423
+ toast: banner === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.Toast, {
8424
+ text: banner.text,
8425
+ holdMs: 5e3,
8426
+ onDone: dismiss
8427
+ }, banner.seq),
8428
+ show: (text) => {
8429
+ seq.current += 1;
8430
+ setBanner({
8431
+ seq: seq.current,
8432
+ text
8433
+ });
8434
+ }
8435
+ };
8436
+ }
8437
+
8302
8438
  //#endregion
8303
8439
  //#region src/client/WorktreeCreateRow.tsx
8304
8440
  function WorktreeCreateRow({ block, services }) {
8305
8441
  const t = useClientTranslator();
8442
+ const desktopAvailable = useHostDesktopAvailable(services.remote);
8443
+ const { toast, show } = useOpenFailureToast();
8306
8444
  const model = parseCreateTool(block, t);
8307
8445
  const [openState, setOpenState] = (0, react.useState)("idle");
8308
8446
  const [openError, setOpenError] = (0, react.useState)(null);
8309
8447
  const payload = model.payload;
8310
8448
  const state = model.lifecycle === "running" ? "running" : model.lifecycle === "ok" ? "ok" : "error";
8449
+ const reveal = async () => {
8450
+ if (!payload) return;
8451
+ const message = await openHostPath(services, payload.managedRoot);
8452
+ if (message !== null) show(message);
8453
+ };
8311
8454
  const openTarget = async () => {
8312
8455
  if (!payload || openState === "opening") return;
8313
8456
  setOpenState("opening");
@@ -8324,83 +8467,90 @@ function WorktreeCreateRow({ block, services }) {
8324
8467
  "data-tool": "worktree_create",
8325
8468
  "data-state": state,
8326
8469
  "aria-label": t("isolated.session.target"),
8327
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
8328
- className: "dsh-wt-head",
8329
- children: [
8330
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8331
- className: "dsh-wt-mark",
8332
- "aria-hidden": true
8333
- }),
8334
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
8335
- className: "dsh-wt-title",
8336
- children: t("isolated.session.target")
8337
- }),
8338
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8339
- className: "dsh-wt-subtitle",
8340
- children: model.lifecycle === "running" ? t("creating.the.unique.worktree") : payload ? t("ready.to.open") : t("creation.failed")
8341
- })
8342
- ]
8343
- }), payload ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8344
- className: "dsh-wt-body",
8345
- children: [
8346
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8347
- className: "dsh-wt-grid",
8348
- children: [
8349
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8350
- className: "dsh-wt-label",
8351
- children: t("checkout")
8352
- }),
8353
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8354
- className: "dsh-wt-value dsh-wt-code",
8355
- children: payload.checkoutId
8356
- }),
8357
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8358
- className: "dsh-wt-label",
8359
- children: t("base")
8360
- }),
8361
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8362
- className: "dsh-wt-value dsh-wt-code",
8363
- children: payload.currentOid.slice(0, 12)
8364
- }),
8365
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8366
- className: "dsh-wt-label",
8367
- children: t("workspace")
8368
- }),
8369
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8470
+ children: [
8471
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
8472
+ className: "dsh-wt-head",
8473
+ children: [
8474
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8475
+ className: "dsh-wt-mark",
8476
+ "aria-hidden": true
8477
+ }),
8478
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
8479
+ className: "dsh-wt-title",
8480
+ children: t("isolated.session.target")
8481
+ }),
8482
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8483
+ className: "dsh-wt-subtitle",
8484
+ children: model.lifecycle === "running" ? t("creating.the.unique.worktree") : payload ? t("ready.to.open") : t("creation.failed")
8485
+ })
8486
+ ]
8487
+ }),
8488
+ payload ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8489
+ className: "dsh-wt-body",
8490
+ children: [
8491
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8492
+ className: "dsh-wt-grid",
8493
+ children: [
8494
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8495
+ className: "dsh-wt-label",
8496
+ children: t("checkout")
8497
+ }),
8498
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8499
+ className: "dsh-wt-value dsh-wt-code",
8500
+ children: payload.checkoutId
8501
+ }),
8502
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8503
+ className: "dsh-wt-label",
8504
+ children: t("base")
8505
+ }),
8506
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8507
+ className: "dsh-wt-value dsh-wt-code",
8508
+ children: payload.currentOid.slice(0, 12)
8509
+ }),
8510
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8511
+ className: "dsh-wt-label",
8512
+ children: t("workspace")
8513
+ }),
8514
+ desktopAvailable === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8515
+ type: "button",
8516
+ className: "dsh-wt-value dsh-wt-code dsh-wt-path",
8517
+ onClick: () => void reveal(),
8518
+ children: payload.managedRoot
8519
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8520
+ className: "dsh-wt-value dsh-wt-code",
8521
+ children: payload.managedRoot
8522
+ })
8523
+ ]
8524
+ }),
8525
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8526
+ className: "dsh-wt-actions",
8527
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8370
8528
  type: "button",
8371
- className: "dsh-wt-value dsh-wt-code dsh-wt-path",
8372
- onClick: () => void services.workspaces.openPath(payload.managedRoot),
8373
- children: payload.managedRoot
8374
- })
8375
- ]
8376
- }),
8377
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8378
- className: "dsh-wt-actions",
8379
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8380
- type: "button",
8381
- className: "dsh-wt-button dsh-wt-primary",
8382
- disabled: openState === "opening",
8383
- onClick: () => void openTarget(),
8384
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "external" }), openState === "opening" ? t("opening.2") : openState === "error" ? t("retry.opening.isolated.session") : t("open.isolated.session")]
8385
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8386
- className: "dsh-wt-status",
8387
- children: t("the.current.local.session.cwd.will.not.be")
8388
- })]
8389
- }),
8390
- openError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8529
+ className: "dsh-wt-button dsh-wt-primary",
8530
+ disabled: openState === "opening",
8531
+ onClick: () => void openTarget(),
8532
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "external" }), openState === "opening" ? t("opening.2") : openState === "error" ? t("retry.opening.isolated.session") : t("open.isolated.session")]
8533
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8534
+ className: "dsh-wt-status",
8535
+ children: t("the.current.local.session.cwd.will.not.be")
8536
+ })]
8537
+ }),
8538
+ openError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8539
+ className: "dsh-wt-error",
8540
+ role: "alert",
8541
+ children: openError
8542
+ }) : null
8543
+ ]
8544
+ }) : model.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8545
+ className: "dsh-wt-body",
8546
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8391
8547
  className: "dsh-wt-error",
8392
8548
  role: "alert",
8393
- children: openError
8394
- }) : null
8395
- ]
8396
- }) : model.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8397
- className: "dsh-wt-body",
8398
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8399
- className: "dsh-wt-error",
8400
- role: "alert",
8401
- children: model.error
8402
- })
8403
- }) : null]
8549
+ children: model.error
8550
+ })
8551
+ }) : null,
8552
+ toast
8553
+ ]
8404
8554
  });
8405
8555
  }
8406
8556
 
@@ -8722,7 +8872,6 @@ const REVIEW_CONSOLE_STYLES = String.raw`
8722
8872
  .dsh-wt-retention-select { display:grid; gap:5px; padding:9px; border-radius:8px; background:var(--wt-panel); font-size:12px; }
8723
8873
  .dsh-wt-retention-select select { min-height:32px; border:1px solid var(--wt-line); border-radius:7px; padding:0 8px; background:Canvas; color:inherit; }
8724
8874
  .dsh-wt-preflight { display:grid; gap:7px; margin-top:7px; padding:8px 9px; border-radius:8px; background:var(--wt-panel); color:var(--wt-muted); font-size:12px; }
8725
- .dsh-wt-preflight[data-preflight="conflict"],
8726
8875
  .dsh-wt-preflight[data-preflight="blocked"],
8727
8876
  .dsh-wt-preflight[data-preflight="error"] { color:var(--wt-amber); }
8728
8877
  .dsh-wt-preflight-head { display:flex; align-items:center; justify-content:space-between; gap:8px; }
@@ -8735,7 +8884,15 @@ const REVIEW_CONSOLE_STYLES = String.raw`
8735
8884
  .dsh-wt-delivery-proof dt { color:var(--wt-muted); }
8736
8885
  .dsh-wt-preflight-facts dd,
8737
8886
  .dsh-wt-delivery-proof dd { min-width:0; margin:0; overflow-wrap:anywhere; }
8738
- .dsh-wt-conflict-list { display:grid; gap:3px; max-height:116px; margin:0; padding-left:18px; overflow:auto; }
8887
+ .dsh-wt-preflight.dsh-wt-conflict { display:flex; align-items:center; flex-wrap:wrap; color:inherit; min-width:0; padding:8px 10px; gap:8px 12px; border:1px solid color-mix(in srgb, var(--wt-amber) 22%, transparent); background:color-mix(in srgb, var(--wt-amber) 5%, transparent); }
8888
+ .dsh-wt-conflict-heading { display:flex; align-items:center; flex:1 1 auto; gap:8px; min-width:0; }
8889
+ .dsh-wt-conflict-heading > div { display:flex; align-items:center; flex-wrap:wrap; gap:2px 10px; min-width:0; }
8890
+ .dsh-wt-conflict-heading > .dsh-wt-icon,
8891
+ .dsh-wt-conflict-heading strong { color:var(--wt-amber); }
8892
+ .dsh-wt-conflict-heading strong { line-height:1.5; overflow-wrap:anywhere; }
8893
+ .dsh-wt-conflict-heading p { margin:0; color:var(--wt-muted); line-height:1.5; }
8894
+ .dsh-wt-conflict-actions { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:8px; margin-left:auto; color:var(--wt-ink); }
8895
+ .dsh-wt-conflict-actions .dsh-wt-button { display:inline-flex; align-items:center; gap:6px; max-width:100%; }
8739
8896
  .dsh-wt-recovery-actions { display:flex; flex-wrap:wrap; gap:6px; }
8740
8897
  .dsh-wt-inline-action { border:0; padding:0; background:transparent; color:inherit; font:inherit; text-decoration:underline; cursor:pointer; }
8741
8898
  .dsh-wt-inline-action:disabled { opacity:.5; cursor:not-allowed; }
@@ -8745,18 +8902,21 @@ const REVIEW_CONSOLE_STYLES = String.raw`
8745
8902
  .dsh-wt-delivery-proof-compact { display:block; margin:1px 0 0; padding:0; border:0; background:transparent; color:var(--wt-muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
8746
8903
  .dsh-wt-action-status { min-height:1.35em; margin-top:7px; color:var(--wt-muted); font-size:12px; }
8747
8904
  .dsh-wt-review-dock { box-sizing:border-box; display:flex; flex:none; align-items:center; gap:9px; width:calc(100% - 2 * var(--dsh-composer-side-clearance, 16px) - 2 * var(--dsh-composer-dock-inset, 0px)); max-width:calc(var(--dsh-composer-card-max-width, 780px) - 2 * var(--dsh-composer-dock-inset, 0px)); margin:0 auto 8px; padding:7px 9px; border:1px solid color-mix(in srgb, #3275db 22%, transparent); border-radius:9px; background:color-mix(in srgb, #3275db 6%, transparent); color:var(--wt-ink); font-size:12px; }
8748
- .dsh-wt-review-dock > .dsh-wt-icon { order:-2; }
8749
- .dsh-wt-review-dock-copy { order:-1; order:-1; display:grid; min-width:0; flex:1; gap:1px; }
8905
+ .dsh-wt-review-dock > .dsh-wt-icon { order:-2; align-self:flex-start; margin-top:6px; }
8906
+ .dsh-wt-review-dock-copy { display:grid; min-width:0; flex:1; gap:1px; }
8750
8907
  .dsh-wt-review-dock-copy strong { font-weight:500; overflow-wrap:anywhere; }
8751
8908
  .dsh-wt-review-dock-copy span { color:var(--wt-muted); font-size:12px; }
8752
- .dsh-wt-review-dock .dsh-wt-review-actions { min-width:0; max-width:100%; padding:0; }
8909
+ .dsh-wt-review-dock .dsh-wt-review-actions { flex:1; min-width:0; max-width:100%; padding:0; }
8910
+ .dsh-wt-review-action-head { display:flex; align-items:center; flex-wrap:wrap; gap:6px 10px; min-width:0; }
8911
+ .dsh-wt-review-action-head > .dsh-wt-review-dock-copy { flex:1 1 180px; }
8912
+ .dsh-wt-review-action-head > .dsh-wt-actions { flex:0 0 auto; margin-left:auto; }
8753
8913
  .dsh-wt-action-status:empty { min-height:0; margin-top:0; }
8754
8914
  .dsh-wt-action-status:empty { min-height:0; margin-top:0; }
8755
8915
  .dsh-wt-review-dock .dsh-wt-action-status:empty { display:none; }
8756
8916
  .dsh-wt-review-evidence-status { margin:0 14px 10px 42px; color:var(--wt-muted); font-size:12px; }
8757
8917
  .dsh-wt-review-dock .dsh-wt-actions { justify-content:flex-end; }
8758
8918
  .dsh-wt-review-dock .dsh-wt-preflight-facts { display:none; }
8759
- .dsh-wt-review-dock .dsh-wt-preflight { margin:0; padding:4px 6px; }
8919
+ .dsh-wt-review-dock .dsh-wt-preflight { margin:8px 0 0; padding:8px 10px; }
8760
8920
  .dsh-wt-review-dock .dsh-wt-preflight[data-preflight="loading"],
8761
8921
  .dsh-wt-review-dock .dsh-wt-preflight[data-preflight="ready"],
8762
8922
  .dsh-wt-review-dock .dsh-wt-preflight[data-preflight="local_advanced"],
@@ -8771,16 +8931,13 @@ const REVIEW_CONSOLE_STYLES = String.raw`
8771
8931
  .dsh-wt-review-validation-details,
8772
8932
  .dsh-wt-review-actions { margin-left:0; padding-left:14px; }
8773
8933
  .dsh-wt-review-dock { flex-wrap:wrap; width:calc(100% - 2 * var(--dsh-composer-side-clearance, 12px) - 2 * var(--dsh-composer-dock-inset, 0px)); }
8774
- .dsh-wt-review-dock > .dsh-wt-icon { order:-2; }
8775
- .dsh-wt-review-dock-copy { order:-1; order:-1; flex-basis:calc(100% - 28px); }
8776
-
8777
- .dsh-wt-review-dock .dsh-wt-review-actions { margin-left:auto; }
8934
+ .dsh-wt-review-dock > .dsh-wt-review-dock-copy { flex-basis:calc(100% - 28px); }
8778
8935
  }
8779
8936
 
8780
8937
  .dsh-wt-icon { display:inline-flex; width:18px; height:18px; flex:0 0 18px; vertical-align:middle; }
8781
8938
  .dsh-wt-review-dock { background:var(--dsw-alias-bg-layer-2, #fff); border-color:var(--wt-line); padding:10px 12px; gap:10px; }
8782
8939
  .dsh-wt-review-dock-copy strong { font-size:13px; font-weight:550; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
8783
- .dsh-wt-review-dock-copy .dsh-wt-dock-evidence { display:flex; align-items:center; gap:5px; }
8940
+ .dsh-wt-review-dock-copy .dsh-wt-dock-evidence { display:flex; align-items:center; flex-wrap:wrap; gap:5px; }
8784
8941
  .dsh-wt-dock-evidence .dsh-wt-icon { width:14px; height:14px; flex-basis:14px; }
8785
8942
  .dsh-wt-details-trigger { display:inline-flex; align-items:center; gap:5px; flex-shrink:0; padding:6px; border:0; background:transparent; color:inherit; font:inherit; cursor:pointer; border-radius:6px; }
8786
8943
  .dsh-wt-details-trigger:hover { background:var(--wt-panel); }
@@ -8797,6 +8954,10 @@ const REVIEW_CONSOLE_STYLES = String.raw`
8797
8954
  .dsh-wt-details-notice[data-tone="warning"] { background:color-mix(in srgb, var(--wt-amber) 8%, transparent); }
8798
8955
  .dsh-wt-details-section { border-top:1px solid var(--wt-line); padding:16px 0; }
8799
8956
  .dsh-wt-details-section h3 { font-size:14px; font-weight:600; margin:0 0 12px; }
8957
+ .dsh-wt-details-list-toggle { display:inline-flex; align-items:center; gap:6px; margin-top:8px; padding:4px 0; border:0; background:transparent; color:var(--wt-muted); font:inherit; cursor:pointer; }
8958
+ .dsh-wt-details-list-toggle:hover { color:var(--wt-ink); }
8959
+ .dsh-wt-details-list-toggle:focus-visible { outline:2px solid #5a8dee; outline-offset:3px; }
8960
+ .dsh-wt-details-list-toggle[aria-expanded="true"] .dsh-wt-icon { transform:rotate(90deg); }
8800
8961
  .dsh-wt-details-files, .dsh-wt-details-tests { padding:0; margin:0; list-style:none; }
8801
8962
  .dsh-wt-details-files li { display:flex; align-items:flex-start; gap:10px; padding:8px 0; }
8802
8963
  .dsh-wt-details-files li > span:nth-child(2) { flex:1; min-width:0; overflow-wrap:anywhere; font-family:ui-monospace, monospace; }
@@ -9064,6 +9225,7 @@ var PreSessionWorktreeController = class {
9064
9225
  if (request.input.phase !== "plain") throw new PreSessionWorktreeError(t("the.draft.is.being.submitted.or.parsed.wait"));
9065
9226
  if (request.input.occurrences.length > 0) throw new PreSessionWorktreeError(t("the.draft.contains.unserialized.references.remove.the.reference"));
9066
9227
  if (!this.services.uiWorkspace?.openSession && !this.services.sessions.open) throw new PreSessionWorktreeError(t("harness.session.navigation.unavailable"));
9228
+ const sourcePreset = (this.services.sessions.list.getSnapshot().byId[request.sessionId]?.projectionValues)?.agentPreset;
9067
9229
  const previousBlock = this.services.conversation.blocks.storeFor(request.sessionId).getSnapshot();
9068
9230
  this.services.conversation.blocks.set(request.sessionId, { reason: t("creating.isolated.worktree") });
9069
9231
  let created;
@@ -9082,7 +9244,8 @@ var PreSessionWorktreeController = class {
9082
9244
  workspaceId = workspace.workspaceId;
9083
9245
  actualSessionId = await this.services.sessions.create({
9084
9246
  workspaceId: workspace.workspaceId,
9085
- sessionId: created.targetSessionId
9247
+ sessionId: created.targetSessionId,
9248
+ ...typeof sourcePreset === "string" ? { agentPreset: sourcePreset } : {}
9086
9249
  });
9087
9250
  if (actualSessionId !== created.targetSessionId) throw new PreSessionWorktreeError(t("harness.created.unexpected.session.expected.2", {
9088
9251
  p0: actualSessionId,
@@ -10002,6 +10165,8 @@ function shortOid$2(value) {
10002
10165
  function TargetStatusAction({ sessionId, adapter, services }) {
10003
10166
  const t = useClientTranslator();
10004
10167
  const language = useClientLanguage();
10168
+ const desktopAvailable = useHostDesktopAvailable(services.remote);
10169
+ const { toast, show } = useOpenFailureToast();
10005
10170
  const [target, setTarget] = (0, react.useState)(null);
10006
10171
  const [loading, setLoading] = (0, react.useState)(true);
10007
10172
  const [error, setError] = (0, react.useState)(null);
@@ -10054,12 +10219,11 @@ function TargetStatusAction({ sessionId, adapter, services }) {
10054
10219
  p0: triggerLabel,
10055
10220
  p1: expiry
10056
10221
  });
10057
- const reveal = () => {
10222
+ const reveal = async () => {
10058
10223
  if (!target?.managedRoot) return;
10059
10224
  setMenuOpen(false);
10060
- services.workspaces.openPath(target.managedRoot).catch((reason) => {
10061
- if (mounted.current) setError(reason instanceof Error ? reason.message : String(reason));
10062
- });
10225
+ const message = await openHostPath(services, target.managedRoot);
10226
+ if (mounted.current && message !== null) show(message);
10063
10227
  };
10064
10228
  const openSource = () => {
10065
10229
  if (!target || target.sourceSessionId === sessionId) return;
@@ -10201,7 +10365,7 @@ function TargetStatusAction({ sessionId, adapter, services }) {
10201
10365
  type: "separator",
10202
10366
  id: "summary-separator"
10203
10367
  },
10204
- ...target?.managedRoot && target.capabilities.open ? [{
10368
+ ...target?.managedRoot && target.capabilities.open && desktopAvailable === true ? [{
10205
10369
  id: "reveal",
10206
10370
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "folder" }),
10207
10371
  label: t("open.current.working.location")
@@ -10313,7 +10477,8 @@ function TargetStatusAction({ sessionId, adapter, services }) {
10313
10477
  children: [t("confirm.worktree.cleanup"), " "]
10314
10478
  })]
10315
10479
  })
10316
- })
10480
+ }),
10481
+ toast
10317
10482
  ] });
10318
10483
  }
10319
10484
 
@@ -10325,6 +10490,28 @@ function validationText(status, t) {
10325
10490
  function validationIcon(status) {
10326
10491
  return status === "passed" ? "check" : status === "failed" || status === "partial" ? "warning" : "minus";
10327
10492
  }
10493
+ const COLLAPSED_LIST_LIMIT = 5;
10494
+ function ReviewDetailsList({ label, className, items }) {
10495
+ const t = useClientTranslator();
10496
+ const listId = (0, react.useId)();
10497
+ const [expanded, setExpanded] = (0, react.useState)(false);
10498
+ const collapsible = items.length > COLLAPSED_LIST_LIMIT;
10499
+ const toggleText = expanded ? t("detail.collapseList") : t("detail.expandList", { count: items.length });
10500
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
10501
+ id: listId,
10502
+ className,
10503
+ "aria-label": label,
10504
+ children: expanded ? items : items.slice(0, COLLAPSED_LIST_LIMIT)
10505
+ }), collapsible ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
10506
+ type: "button",
10507
+ className: "dsh-wt-details-list-toggle",
10508
+ "aria-label": `${label}: ${toggleText}`,
10509
+ "aria-expanded": expanded,
10510
+ "aria-controls": listId,
10511
+ onClick: () => setExpanded((value) => !value),
10512
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "chevron" }), toggleText]
10513
+ }) : null] });
10514
+ }
10328
10515
  function ReviewDetailsModal({ open, onClose, target, preflight }) {
10329
10516
  const t = useClientTranslator();
10330
10517
  const content = (0, react.useRef)(null);
@@ -10356,6 +10543,7 @@ function ReviewDetailsModal({ open, onClose, target, preflight }) {
10356
10543
  }, [open]);
10357
10544
  const review = target.review;
10358
10545
  if (!review) return null;
10546
+ const listKey = `${target.checkoutId}:${review.reviewId}:${target.revision}:${open}`;
10359
10547
  const conflict = preflight?.status === "conflict";
10360
10548
  const recovery = target.state === "preview_detached" || target.state === "recovery_required";
10361
10549
  const state = recovery ? "detail.recovery" : conflict || preflight?.status === "blocked" ? "detail.blocked" : target.state === "preview_active" ? "detail.preview" : target.state === "retained" || target.state === "delivered" || target.state === "cleanup_pending" ? "detail.saved" : "detail.ready";
@@ -10403,11 +10591,20 @@ function ReviewDetailsModal({ open, onClose, target, preflight }) {
10403
10591
  "data-tone": recovery || conflict || preflight?.status === "blocked" ? "warning" : "neutral",
10404
10592
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: recovery || conflict ? "warning" : "list" }), note]
10405
10593
  }) : null,
10594
+ conflict ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
10595
+ className: "dsh-wt-details-section",
10596
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("conflicting.files") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewDetailsList, {
10597
+ label: t("conflicting.files"),
10598
+ className: "dsh-wt-details-files",
10599
+ items: preflight.conflictingFiles.map((file) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "file" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: file })] }, file))
10600
+ }, `conflicts:${listKey}:${JSON.stringify(preflight.conflictingFiles)}`)]
10601
+ }) : null,
10406
10602
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
10407
10603
  className: "dsh-wt-details-section",
10408
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("detail.files") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
10604
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("detail.files") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewDetailsList, {
10605
+ label: t("detail.files"),
10409
10606
  className: "dsh-wt-details-files",
10410
- children: review.changedFiles.map((file) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
10607
+ items: review.changedFiles.map((file) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
10411
10608
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "file" }),
10412
10609
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: file }),
10413
10610
  conflict && preflight.conflictingFiles.includes(file) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -10416,7 +10613,7 @@ function ReviewDetailsModal({ open, onClose, target, preflight }) {
10416
10613
  children: t("detail.conflict")
10417
10614
  }) : null
10418
10615
  ] }, file))
10419
- })]
10616
+ }, `files:${listKey}`)]
10420
10617
  }),
10421
10618
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
10422
10619
  className: "dsh-wt-details-section",
@@ -10426,16 +10623,17 @@ function ReviewDetailsModal({ open, onClose, target, preflight }) {
10426
10623
  className: "dsh-wt-details-muted",
10427
10624
  children: review.validationSummary
10428
10625
  }) : null,
10429
- review.tests.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
10626
+ review.tests.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewDetailsList, {
10627
+ label: t("detail.validation"),
10430
10628
  className: "dsh-wt-details-tests",
10431
- children: review.tests.map((test, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: validationIcon(test.status) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10629
+ items: review.tests.map((test, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: validationIcon(test.status) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10432
10630
  className: "dsh-wt-details-test-title",
10433
10631
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: test.command }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10434
10632
  "data-validation": test.status,
10435
10633
  children: validationText(test.status, t)
10436
10634
  })]
10437
10635
  }), test.summary ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: test.summary }) : null] })] }, index))
10438
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10636
+ }, `tests:${listKey}`) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10439
10637
  className: "dsh-wt-details-muted",
10440
10638
  children: t("detail.noTests")
10441
10639
  })
@@ -10658,6 +10856,29 @@ function PreflightStatus({ snapshot, target, compact = false, onRefresh, onRecov
10658
10856
  })]
10659
10857
  });
10660
10858
  const preflight = snapshot.preflight;
10859
+ if (preflight.status === "conflict") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10860
+ className: "dsh-wt-preflight dsh-wt-conflict",
10861
+ "data-preflight": "conflict",
10862
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10863
+ className: "dsh-wt-conflict-heading",
10864
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "warning" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: statusLabel(preflight, t) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("read.only.check.local.unchanged") })] })]
10865
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10866
+ className: "dsh-wt-conflict-actions",
10867
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
10868
+ type: "button",
10869
+ className: "dsh-wt-button",
10870
+ disabled: busy,
10871
+ onClick: onRefresh,
10872
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "refresh" }), t("check.again")]
10873
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
10874
+ type: "button",
10875
+ className: "dsh-wt-button dsh-wt-primary",
10876
+ disabled: busy || !target?.capabilities.resumeRevision,
10877
+ onClick: () => onRecovery(preflight),
10878
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "warning" }), t("ask.agent.to.resolve.conflicts")]
10879
+ })]
10880
+ })]
10881
+ });
10661
10882
  const blocked = preflight.status === "blocked";
10662
10883
  const staleIsolated = blocked && preflight.reason === "stale_isolated" && preflight.reviewId !== null;
10663
10884
  const holder = blocked && preflight.reason === "project_acceptance_busy" ? preflight.blocker ?? target?.reviewSlotHolder : void 0;
@@ -10682,11 +10903,6 @@ function PreflightStatus({ snapshot, target, compact = false, onRefresh, onRecov
10682
10903
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("changes") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: t("count.files", { count: preflight.changedFiles.length }) })] })
10683
10904
  ]
10684
10905
  }) : null,
10685
- !compact && preflight.status === "conflict" && preflight.conflictingFiles.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
10686
- className: "dsh-wt-conflict-list",
10687
- "aria-label": t("conflicting.files"),
10688
- children: preflight.conflictingFiles.map((path) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: path }) }, path))
10689
- }) : null,
10690
10906
  holder ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [
10691
10907
  t("holding.task"),
10692
10908
  holder.checkoutId.slice(0, 8),
@@ -10705,7 +10921,7 @@ function PreflightStatus({ snapshot, target, compact = false, onRefresh, onRecov
10705
10921
  delivered: t("delivered")
10706
10922
  }[holder.state]
10707
10923
  ] }) : null,
10708
- preflight.status === "conflict" || blocked ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10924
+ blocked ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10709
10925
  className: "dsh-wt-recovery-actions",
10710
10926
  children: [
10711
10927
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
@@ -10715,17 +10931,7 @@ function PreflightStatus({ snapshot, target, compact = false, onRefresh, onRecov
10715
10931
  onClick: onRefresh,
10716
10932
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "refresh" }), t("check.again")]
10717
10933
  }),
10718
- preflight.status === "conflict" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
10719
- type: "button",
10720
- className: "dsh-wt-inline-action",
10721
- disabled: busy || !target?.capabilities.resumeRevision,
10722
- onClick: () => onRecovery(preflight),
10723
- children: [
10724
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "warning" }),
10725
- t("ask.agent.to.resolve.conflicts"),
10726
- " "
10727
- ]
10728
- }) : staleIsolated ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
10934
+ staleIsolated ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
10729
10935
  type: "button",
10730
10936
  className: "dsh-wt-inline-action",
10731
10937
  disabled: busy,
@@ -11673,7 +11879,7 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
11673
11879
  const checkpoint = async () => {
11674
11880
  const value = checkpointMessage.trim();
11675
11881
  const requestId = checkpointRequestId.current;
11676
- if (!value || value.length > 500 || !requestId || !begin("checkpoint") || !adapter || !identity || !target?.checkpointGeneration) return;
11882
+ if (!isValidCommitMessage(value) || !requestId || !begin("checkpoint") || !adapter || !identity || !target?.checkpointGeneration) return;
11677
11883
  const expectedCount = target.checkpoints?.length ?? 0;
11678
11884
  const outcome = await adapter.checkpoint({
11679
11885
  ...identity,
@@ -11787,7 +11993,7 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
11787
11993
  const submitCommit = async () => {
11788
11994
  const value = commitMessage.trim();
11789
11995
  const mode = commitMode;
11790
- if (!mode || !value || value.length > 500 || !begin(mode) || !adapter || !identity) return;
11996
+ if (!mode || !isValidCommitMessage(value) || !begin(mode) || !adapter || !identity) return;
11791
11997
  const selectedRetention = retainEnvironment ? retention : "cleanup";
11792
11998
  const request = {
11793
11999
  ...identity,
@@ -12124,7 +12330,7 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
12124
12330
  },
12125
12331
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "refresh" }), submitting === "retry_cleanup" ? t("cleaning.up") : t("retry.environment.cleanup")]
12126
12332
  }) : null;
12127
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [renderStatus?.(submitting), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
12333
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
12128
12334
  className: "dsh-wt-review-actions",
12129
12335
  "aria-label": t("review.actions"),
12130
12336
  children: [
@@ -12132,123 +12338,126 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
12132
12338
  className: "dsh-wt-status",
12133
12339
  children: unavailableMessage
12134
12340
  }) : null,
12135
- terminal ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
12136
- className: "dsh-wt-status",
12137
- children: target.state === "retained" ? t("this.iteration.was.committed.the.environment.is.temporarily", { p0: target.commitOid ? ` · ${target.commitOid.slice(0, 8)}` : "" }) : t("this.iteration.was.delivered", { p0: target.commitOid ? ` · ${target.commitOid.slice(0, 8)}` : "" })
12138
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12139
- className: "dsh-wt-actions",
12140
- children: [primary, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
12141
- ref: moreMenuRef,
12142
- className: "dsh-wt-more-menu",
12143
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", {
12144
- className: "dsh-wt-more-trigger",
12145
- "aria-label": t("more.delivery.actions"),
12146
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "more" })
12147
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12148
- className: "dsh-wt-more-content",
12149
- role: "menu",
12150
- children: [
12151
- focusReview && !renderStatus ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12152
- type: "button",
12153
- role: "menuitem",
12154
- className: "dsh-wt-more-item",
12155
- onClick: () => {
12156
- focusReview();
12157
- closeMoreMenu();
12158
- },
12159
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "list" }), t("view.review")]
12160
- }) : null,
12161
- ready ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
12162
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12341
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12342
+ className: renderStatus ? "dsh-wt-review-action-head" : void 0,
12343
+ children: [renderStatus?.(submitting), terminal ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
12344
+ className: "dsh-wt-status",
12345
+ children: target.state === "retained" ? t("this.iteration.was.committed.the.environment.is.temporarily", { p0: target.commitOid ? ` · ${target.commitOid.slice(0, 8)}` : "" }) : t("this.iteration.was.delivered", { p0: target.commitOid ? ` · ${target.commitOid.slice(0, 8)}` : "" })
12346
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12347
+ className: "dsh-wt-actions",
12348
+ children: [ready && preflightSnapshot.status === "success" && preflightSnapshot.preflight.status === "conflict" ? null : primary, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
12349
+ ref: moreMenuRef,
12350
+ className: "dsh-wt-more-menu",
12351
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", {
12352
+ className: "dsh-wt-more-trigger",
12353
+ "aria-label": t("more.delivery.actions"),
12354
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "more" })
12355
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12356
+ className: "dsh-wt-more-content",
12357
+ role: "menu",
12358
+ children: [
12359
+ focusReview && !renderStatus ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12360
+ type: "button",
12361
+ role: "menuitem",
12362
+ className: "dsh-wt-more-item",
12363
+ onClick: () => {
12364
+ focusReview();
12365
+ closeMoreMenu();
12366
+ },
12367
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "list" }), t("view.review")]
12368
+ }) : null,
12369
+ ready ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
12370
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12371
+ type: "button",
12372
+ role: "menuitem",
12373
+ className: "dsh-wt-more-item",
12374
+ disabled: allDisabled || !target.capabilities.checkpoint || !target.checkpointGeneration,
12375
+ onClick: () => {
12376
+ openCheckpoint();
12377
+ closeMoreMenu();
12378
+ },
12379
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "save" }), t("save.stage.and.continue")]
12380
+ }),
12381
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12382
+ type: "button",
12383
+ role: "menuitem",
12384
+ className: "dsh-wt-more-item",
12385
+ disabled: allDisabled || !target.capabilities.resumeRevision,
12386
+ onClick: () => {
12387
+ resumeRevision();
12388
+ closeMoreMenu();
12389
+ },
12390
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "edit" }), submitting === "resume_revision" ? t("recovering") : t("continue.editing")]
12391
+ }),
12392
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12393
+ type: "button",
12394
+ role: "menuitem",
12395
+ className: "dsh-wt-more-item",
12396
+ disabled: allDisabled || !target.capabilities.finalize || !safeReadyPreflight,
12397
+ onClick: () => {
12398
+ setCommitMode("finish");
12399
+ closeMoreMenu();
12400
+ },
12401
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "confirm" }), t("skip.preview.and.save")]
12402
+ })
12403
+ ] }) : null,
12404
+ previewActive && target.capabilities.checkpoint && target.checkpointGeneration ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12163
12405
  type: "button",
12164
12406
  role: "menuitem",
12165
12407
  className: "dsh-wt-more-item",
12166
- disabled: allDisabled || !target.capabilities.checkpoint || !target.checkpointGeneration,
12408
+ disabled: allDisabled,
12167
12409
  onClick: () => {
12168
12410
  openCheckpoint();
12169
12411
  closeMoreMenu();
12170
12412
  },
12171
12413
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "save" }), t("save.stage.and.continue")]
12172
- }),
12173
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12414
+ }) : null,
12415
+ previewActive ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12174
12416
  type: "button",
12175
12417
  role: "menuitem",
12176
12418
  className: "dsh-wt-more-item",
12177
- disabled: allDisabled || !target.capabilities.resumeRevision,
12419
+ disabled: allDisabled || !target.capabilities.rollbackPreview,
12178
12420
  onClick: () => {
12179
- resumeRevision();
12421
+ rollbackPreview(true);
12180
12422
  closeMoreMenu();
12181
12423
  },
12182
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "edit" }), submitting === "resume_revision" ? t("recovering") : t("continue.editing")]
12183
- }),
12184
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12424
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "edit" }), t("continue.editing")]
12425
+ }) : null,
12426
+ previewActive || rollbackRecoverySafe ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12185
12427
  type: "button",
12186
12428
  role: "menuitem",
12187
12429
  className: "dsh-wt-more-item",
12188
- disabled: allDisabled || !target.capabilities.finalize || !safeReadyPreflight,
12430
+ disabled: allDisabled || !target.capabilities.rollbackPreview,
12189
12431
  onClick: () => {
12190
- setCommitMode("finish");
12432
+ rollbackPreview();
12191
12433
  closeMoreMenu();
12192
12434
  },
12193
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "confirm" }), t("skip.preview.and.save")]
12194
- })
12195
- ] }) : null,
12196
- previewActive && target.capabilities.checkpoint && target.checkpointGeneration ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12197
- type: "button",
12198
- role: "menuitem",
12199
- className: "dsh-wt-more-item",
12200
- disabled: allDisabled,
12201
- onClick: () => {
12202
- openCheckpoint();
12203
- closeMoreMenu();
12204
- },
12205
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "save" }), t("save.stage.and.continue")]
12206
- }) : null,
12207
- previewActive ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12208
- type: "button",
12209
- role: "menuitem",
12210
- className: "dsh-wt-more-item",
12211
- disabled: allDisabled || !target.capabilities.rollbackPreview,
12212
- onClick: () => {
12213
- rollbackPreview(true);
12214
- closeMoreMenu();
12215
- },
12216
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "edit" }), t("continue.editing")]
12217
- }) : null,
12218
- previewActive || rollbackRecoverySafe ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12219
- type: "button",
12220
- role: "menuitem",
12221
- className: "dsh-wt-more-item",
12222
- disabled: allDisabled || !target.capabilities.rollbackPreview,
12223
- onClick: () => {
12224
- rollbackPreview();
12225
- closeMoreMenu();
12226
- },
12227
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "rollback" }), previewActive ? t("roll.back.this.preview") : t("retry.rollback")]
12228
- }) : null,
12229
- finalizeRecoverySafe ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12230
- type: "button",
12231
- role: "menuitem",
12232
- className: "dsh-wt-more-item",
12233
- disabled: allDisabled || !target.capabilities.finalizePreview,
12234
- onClick: () => {
12235
- setCommitMode("finalize_preview");
12236
- closeMoreMenu();
12237
- },
12238
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "confirm" }), t("save.changes")]
12239
- }) : null,
12240
- canDiscard ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12241
- type: "button",
12242
- role: "menuitem",
12243
- className: "dsh-wt-more-item dsh-wt-danger-text",
12244
- disabled: allDisabled,
12245
- onClick: () => {
12246
- setDiscardOpen(true);
12247
- closeMoreMenu();
12248
- },
12249
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "discard" }), t("discard.task")]
12250
- }) : null
12251
- ]
12435
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "rollback" }), previewActive ? t("roll.back.this.preview") : t("retry.rollback")]
12436
+ }) : null,
12437
+ finalizeRecoverySafe ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12438
+ type: "button",
12439
+ role: "menuitem",
12440
+ className: "dsh-wt-more-item",
12441
+ disabled: allDisabled || !target.capabilities.finalizePreview,
12442
+ onClick: () => {
12443
+ setCommitMode("finalize_preview");
12444
+ closeMoreMenu();
12445
+ },
12446
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "confirm" }), t("save.changes")]
12447
+ }) : null,
12448
+ canDiscard ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12449
+ type: "button",
12450
+ role: "menuitem",
12451
+ className: "dsh-wt-more-item dsh-wt-danger-text",
12452
+ disabled: allDisabled,
12453
+ onClick: () => {
12454
+ setDiscardOpen(true);
12455
+ closeMoreMenu();
12456
+ },
12457
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "discard" }), t("discard.task")]
12458
+ }) : null
12459
+ ]
12460
+ })]
12252
12461
  })]
12253
12462
  })]
12254
12463
  }),
@@ -12269,7 +12478,7 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
12269
12478
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12270
12479
  type: "button",
12271
12480
  className: "dsh-wt-button dsh-wt-primary",
12272
- disabled: submitting !== null || !checkpointMessage.trim() || checkpointMessage.trim().length > 500,
12481
+ disabled: submitting !== null || !isValidCommitMessage(checkpointMessage),
12273
12482
  onClick: () => {
12274
12483
  checkpoint();
12275
12484
  },
@@ -12291,13 +12500,12 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
12291
12500
  id: `${formId}-checkpoint-message`,
12292
12501
  "aria-label": t("checkpoint.commit.message"),
12293
12502
  rows: 6,
12294
- maxLength: 500,
12295
12503
  value: checkpointMessage,
12296
12504
  onChange: (event) => setCheckpointMessage(event.target.value)
12297
12505
  }),
12298
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12506
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
12299
12507
  className: "dsh-wt-character-count",
12300
- children: [checkpointMessage.length, t("500")]
12508
+ children: checkpointMessage.length
12301
12509
  })
12302
12510
  ]
12303
12511
  })
@@ -12319,7 +12527,7 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
12319
12527
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12320
12528
  type: "button",
12321
12529
  className: "dsh-wt-button dsh-wt-primary",
12322
- disabled: submitting !== null || !commitMessage.trim() || commitMessage.trim().length > 500,
12530
+ disabled: submitting !== null || !isValidCommitMessage(commitMessage),
12323
12531
  onClick: () => {
12324
12532
  submitCommit();
12325
12533
  },
@@ -12337,13 +12545,12 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
12337
12545
  id: `${formId}-message`,
12338
12546
  "aria-label": t("commit.message"),
12339
12547
  rows: 6,
12340
- maxLength: 500,
12341
12548
  value: commitMessage,
12342
12549
  onChange: (event) => setCommitMessage(event.target.value)
12343
12550
  }),
12344
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12551
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
12345
12552
  className: "dsh-wt-character-count",
12346
- children: [commitMessage.length, t("500")]
12553
+ children: commitMessage.length
12347
12554
  }),
12348
12555
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
12349
12556
  className: "dsh-wt-retention-check",
@@ -12559,7 +12766,7 @@ function ReviewActions({ review, adapter, services, identity, target, disabled,
12559
12766
  }), " "]
12560
12767
  }) : null
12561
12768
  ]
12562
- })] });
12769
+ }) });
12563
12770
  }
12564
12771
 
12565
12772
  //#endregion
@@ -12699,12 +12906,6 @@ function WorktreeReviewStatus({ session, adapter, services }) {
12699
12906
  className: "dsh-wt-error",
12700
12907
  children: error
12701
12908
  }) : null,
12702
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12703
- type: "button",
12704
- className: "dsh-wt-details-trigger",
12705
- onClick: () => setDetailsOpen(true),
12706
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "list" }), t("detail.view")]
12707
- }),
12708
12909
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewDetailsModal, {
12709
12910
  open: detailsOpen,
12710
12911
  onClose: () => setDetailsOpen(false),
@@ -12720,7 +12921,7 @@ function WorktreeReviewStatus({ session, adapter, services }) {
12720
12921
  disabled: false,
12721
12922
  unavailableMessage: t("live.worktree.console.is.disconnected"),
12722
12923
  focusReview: () => setDetailsOpen(true),
12723
- renderStatus: (operation) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
12924
+ renderStatus: (operation) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
12724
12925
  className: "dsh-wt-review-dock-copy",
12725
12926
  role: "status",
12726
12927
  "aria-live": "polite",
@@ -12741,7 +12942,12 @@ function WorktreeReviewStatus({ session, adapter, services }) {
12741
12942
  }),
12742
12943
  target.state === "preview_detached" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: detail }) : null
12743
12944
  ]
12744
- }),
12945
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
12946
+ type: "button",
12947
+ className: "dsh-wt-details-trigger",
12948
+ onClick: () => setDetailsOpen(true),
12949
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReviewIcon, { name: "list" }), t("detail.view")]
12950
+ })] }),
12745
12951
  isActive: () => mounted.current && currentSessionId.current === sessionId && sessionGeneration.current === actionGeneration,
12746
12952
  onStale: () => {
12747
12953
  refresh();
@@ -12942,14 +13148,21 @@ const TARGET_CONSOLE_STYLES = String.raw`
12942
13148
  //#region src/client/index.tsx
12943
13149
  /** Browser entry: dedicated ToolViews for Worktree target handoff and review. */
12944
13150
  const WORKTREE_CONSOLE_ADAPTER_SERVICE = "worktreeConsole";
12945
- /** Required client services. */
13151
+ /**
13152
+ * Required client services.
13153
+ * `remote.session` carries the Host desktop face; cordis refuses the nested
13154
+ * `remote.session` read without this declaration, so the access would throw
13155
+ * instead of returning undefined.
13156
+ */
12946
13157
  const inject$1 = [
12947
13158
  "slots",
12948
13159
  "workspaces",
12949
13160
  "sessions",
12950
13161
  "conversation",
12951
13162
  "connection",
12952
- "locale"
13163
+ "locale",
13164
+ "remote",
13165
+ "remote.session"
12953
13166
  ];
12954
13167
  function servicesOf(ctx) {
12955
13168
  return {
@@ -12957,12 +13170,14 @@ function servicesOf(ctx) {
12957
13170
  workspaces: ctx.get("workspaces"),
12958
13171
  sessions: ctx.get("sessions"),
12959
13172
  uiWorkspace: ctx.get("uiWorkspace"),
12960
- conversation: ctx.get("conversation")
13173
+ conversation: ctx.get("conversation"),
13174
+ remote: ctx.get("remote")
12961
13175
  };
12962
13176
  }
12963
13177
  /** Register replay-stable keyed rows and one scoped stylesheet. */
12964
13178
  function apply$1(ctx, adapterOverride) {
12965
13179
  const services = servicesOf(ctx);
13180
+ prefetchHostDesktop(services.remote);
12966
13181
  const locale = services.locale;
12967
13182
  const localizedSlots = new Proxy(ctx.slots, { get(target, key, receiver) {
12968
13183
  if (key === "register") return (descriptor$1, Component) => target.register(descriptor$1, (props) => (0, react.createElement)(ClientI18nProvider, {
@@ -13018,10 +13233,10 @@ const official$2 = ((require$1) => {
13018
13233
  var exports$1 = module$1.exports;
13019
13234
  Object.defineProperty(exports$1, Symbol.toStringTag, { value: "Module" });
13020
13235
  let _deepseek_ai_dsh_client_store = require$1("@deepseek-ai/dsh-client-store");
13236
+ let _deepseek_ai_dsh_client_ui_primitives = require$1("@deepseek-ai/dsh-client-ui-primitives");
13021
13237
  let _deepseek_ai_cordis = require$1("@deepseek-ai/cordis");
13022
13238
  let react_jsx_runtime$1 = require$1("react/jsx-runtime");
13023
13239
  let react$1 = require$1("react");
13024
- let _deepseek_ai_dsh_client_ui_primitives = require$1("@deepseek-ai/dsh-client-ui-primitives");
13025
13240
  /**
13026
13241
  * Bind the row's render occurrence into the entries' `useMenuOpenState` hook:
13027
13242
  * the owner supplies its open-state pair as the occurrence's `hookContext`,
@@ -13040,10 +13255,8 @@ const official$2 = ((require$1) => {
13040
13255
  searchRequest: 0,
13041
13256
  addRequested: false,
13042
13257
  directoryBusy: false,
13043
- renameTarget: null,
13044
- forkError: null
13258
+ renameTarget: null
13045
13259
  });
13046
- let forkErrorSeq = 0;
13047
13260
  return {
13048
13261
  state,
13049
13262
  search: () => {
@@ -13084,22 +13297,6 @@ const official$2 = ((require$1) => {
13084
13297
  ...state.getSnapshot(),
13085
13298
  renameTarget: null
13086
13299
  });
13087
- },
13088
- forkFailed: (reason) => {
13089
- forkErrorSeq += 1;
13090
- state.set({
13091
- ...state.getSnapshot(),
13092
- forkError: {
13093
- reason,
13094
- seq: forkErrorSeq
13095
- }
13096
- });
13097
- },
13098
- dismissForkError: () => {
13099
- state.set({
13100
- ...state.getSnapshot(),
13101
- forkError: null
13102
- });
13103
13300
  }
13104
13301
  };
13105
13302
  }
@@ -13110,8 +13307,9 @@ const official$2 = ((require$1) => {
13110
13307
  * @param navigation - session creation and forking from the pointer controls' navigation service.
13111
13308
  * @param controls - browser-owned opening requests.
13112
13309
  * @param archiveSession - shared archive action, including running-work confirmation and notices.
13310
+ * @param reportForkFailure - publish a classified failure through the frame-wide notice channel.
13113
13311
  */
13114
- function installWorkspaceShortcuts(ctx, navigation, controls, archiveSession) {
13312
+ function installWorkspaceShortcuts(ctx, navigation, controls, archiveSession, reportForkFailure) {
13115
13313
  const t = ctx.locale.bind("workspace");
13116
13314
  const current = () => Object.values(ctx.sessions.list.getSnapshot().byId).find((row) => (row.retainedBy.mainView ?? 0) > 0);
13117
13315
  const addReason = () => ctx.slots.entries("sidebar.workspaces.directoryFlow").length === 0 ? t("shortcut.noPicker") : controls.state.getSnapshot().directoryBusy ? t("shortcut.directoryBusy") : null;
@@ -13194,7 +13392,7 @@ const official$2 = ((require$1) => {
13194
13392
  run: () => {
13195
13393
  navigation.forkSession(target.id).catch((error) => {
13196
13394
  const unavailable = error instanceof Error && error.name === "SessionForkError" && error.rpcError.code === "session/fork-unavailable";
13197
- controls.forkFailed(unavailable ? "unavailable" : "failed");
13395
+ reportForkFailure(unavailable ? "unavailable" : "failed");
13198
13396
  if (!unavailable) console.warn("session fork rejected:", error);
13199
13397
  });
13200
13398
  }
@@ -13214,16 +13412,636 @@ const official$2 = ((require$1) => {
13214
13412
  });
13215
13413
  }
13216
13414
  /**
13217
- * Mark an unreachable closed-union branch.
13218
- * @param value - impossible value; an unhandled typed variant fails at the call site.
13219
- * @param context - optional switch-site label included in the failure message.
13220
- * @returns never; a runtime value that escaped its type always throws.
13415
+ * Lazily scanned view of one JSON object's top-level fields, built from text
13416
+ * that may still be streaming or from an already parsed object. Nothing is
13417
+ * scanned until a reader asks; the view remembers every question it answered
13418
+ * and reports changed answers when the owner refreshes for publication.
13419
+ * Used for model tool-call arguments: a row reads the fields it
13420
+ * cares about at whatever granularity it displays, at every stage of the call.
13421
+ * @module @deepseek-ai/dsh-util-values/src/partial-json
13221
13422
  */
13222
- function assertNever$1(value, context) {
13223
- const rendered = JSON.stringify(value) ?? String(value);
13224
- throw new Error(`unreachable variant${context ? ` in ${context}` : ""}: ${rendered}`);
13423
+ const SIMPLE_ESCAPES = {
13424
+ "\"": "\"",
13425
+ "\\": "\\",
13426
+ "/": "/",
13427
+ b: "\b",
13428
+ f: "\f",
13429
+ n: "\n",
13430
+ r: "\r",
13431
+ t: " "
13432
+ };
13433
+ const CONTENT_ESCAPE = /[\\\u0000-\u001f]/u;
13434
+ function isWhitespace(c) {
13435
+ return c === " " || c === "\n" || c === "\r" || c === " ";
13225
13436
  }
13226
- /** Whether a path uses a Windows drive or UNC prefix. */
13437
+ function isHex(c) {
13438
+ return c >= "0" && c <= "9" || c >= "a" && c <= "f" || c >= "A" && c <= "F";
13439
+ }
13440
+ (class PartialArguments {
13441
+ /** The view of a call with no arguments available. */
13442
+ static EMPTY = PartialArguments.fromObject({});
13443
+ /**
13444
+ * View finished argument text without scanning it until a reader asks.
13445
+ * @param text - the complete argument JSON text.
13446
+ * @returns a sealed view.
13447
+ */
13448
+ static fromText(text) {
13449
+ const view = new PartialArguments();
13450
+ view.append(text);
13451
+ view.sealed = true;
13452
+ return view;
13453
+ }
13454
+ /**
13455
+ * View an already parsed argument payload, such as a PTC dispatch object.
13456
+ * @param value - the parsed argument value.
13457
+ * @returns a sealed view; a non-object payload has no fields.
13458
+ */
13459
+ static fromObject(value) {
13460
+ const view = new PartialArguments();
13461
+ view.object = typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
13462
+ view.sealed = true;
13463
+ return view;
13464
+ }
13465
+ /**
13466
+ * The source: text so far or a parsed object, plus whether it can still grow.
13467
+ * These are the only enumerable fields, so two views over the same source
13468
+ * compare equal structurally however far each has been read.
13469
+ */
13470
+ chunks = [];
13471
+ object;
13472
+ sealed = false;
13473
+ #ends = [];
13474
+ #size = 0;
13475
+ #consumed = 0;
13476
+ #mode = "root";
13477
+ #escape = false;
13478
+ #keyStart = 0;
13479
+ #keyEscaped = false;
13480
+ #key = "";
13481
+ #current = null;
13482
+ #nestedEnds = [];
13483
+ #nestedInString = false;
13484
+ #invalidAt;
13485
+ #invalidValue = false;
13486
+ #entries = /* @__PURE__ */ new Map();
13487
+ #order = [];
13488
+ #reads = /* @__PURE__ */ new Map();
13489
+ /** Whether this view rejects further appends; does not scan text or register reads. */
13490
+ get isSealed() {
13491
+ return this.sealed;
13492
+ }
13493
+ /** Whether indexing or a content read found invalid JSON; unread value contents are not validated. */
13494
+ get invalid() {
13495
+ this.scan();
13496
+ return this.#mode === "invalid" || this.#invalidValue;
13497
+ }
13498
+ /**
13499
+ * Retain streamed argument text without scanning or comparing observed answers.
13500
+ * @param fragment - the text following every fragment appended before.
13501
+ */
13502
+ append(fragment) {
13503
+ if (this.sealed) throw new Error("PartialArguments: cannot append to a sealed view");
13504
+ if (fragment.length === 0) return;
13505
+ this.chunks.push(fragment);
13506
+ this.#size += fragment.length;
13507
+ this.#ends.push(this.#size);
13508
+ }
13509
+ /**
13510
+ * Reconcile a streamed prefix with authoritative complete text without joining the fragments.
13511
+ * @param text - the final argument text, which replaces missing or conflicting deltas.
13512
+ * @returns this view sealed with its caches retained when every character matches; otherwise a new sealed view.
13513
+ */
13514
+ settle(text) {
13515
+ if (this.object !== void 0 || text.length !== this.#size) return PartialArguments.fromText(text);
13516
+ let offset = 0;
13517
+ for (const chunk of this.chunks) {
13518
+ if (!text.startsWith(chunk, offset)) return PartialArguments.fromText(text);
13519
+ offset += chunk.length;
13520
+ }
13521
+ this.chunks = text.length === 0 ? [] : [text];
13522
+ this.#ends = text.length === 0 ? [] : [text.length];
13523
+ this.sealed = true;
13524
+ return this;
13525
+ }
13526
+ /**
13527
+ * Compare observed answers and advance their publication baseline. Unread views remain unscanned.
13528
+ * @returns whether any observed answer changed since its first read or the preceding refresh.
13529
+ */
13530
+ refresh() {
13531
+ if (this.#reads.size === 0) return false;
13532
+ this.scan();
13533
+ let changed = false;
13534
+ let completions = false;
13535
+ for (const read of this.#reads.values()) {
13536
+ if (read.completion) {
13537
+ completions = true;
13538
+ continue;
13539
+ }
13540
+ changed = this.refreshRead(read) || changed;
13541
+ }
13542
+ if (completions) {
13543
+ for (const read of this.#reads.values()) if (read.completion) changed = this.refreshRead(read) || changed;
13544
+ }
13545
+ if (this.sealed) this.#reads.clear();
13546
+ return changed;
13547
+ }
13548
+ refreshRead(read) {
13549
+ const now = read.answer();
13550
+ if (Object.is(now, read.last)) return false;
13551
+ read.last = now;
13552
+ return true;
13553
+ }
13554
+ /**
13555
+ * Check whether no further fields can arrive.
13556
+ * @returns whether the outer object closed, indexing failed, or the view is sealed; unread values are not validated.
13557
+ */
13558
+ closed() {
13559
+ return this.remember("closed", "", () => this.closedNow());
13560
+ }
13561
+ /**
13562
+ * List discovered fields in first-appearance order.
13563
+ * @returns top-level keys seen so far, in first-appearance order.
13564
+ */
13565
+ keys() {
13566
+ return this.remember("keys", "", () => this.keysNow(), (keys) => keys.length);
13567
+ }
13568
+ /**
13569
+ * Check whether a top-level field has appeared.
13570
+ * @param key - argument name.
13571
+ * @returns whether the field has appeared (a string opened or another value began).
13572
+ */
13573
+ has(key) {
13574
+ return this.remember("has", key, () => this.hasNow(key));
13575
+ }
13576
+ /**
13577
+ * Check whether a field's closing delimiter has arrived, without validating its contents.
13578
+ * @param key - argument name.
13579
+ * @returns whether its delimiter arrived and no content reader has reported an error for this value.
13580
+ */
13581
+ complete(key) {
13582
+ return this.remember("complete", key, () => this.completeNow(key));
13583
+ }
13584
+ /**
13585
+ * Read string length without materializing its text.
13586
+ * @param key - argument name.
13587
+ * @param options - change granularity for a streaming string.
13588
+ * @returns decoded UTF-16 length of the string field so far; undefined when absent or not a string.
13589
+ */
13590
+ stringLength(key, options) {
13591
+ const step = Math.max(1, Math.floor(options?.step ?? 1));
13592
+ const offset = options?.offset ?? 0;
13593
+ return this.remember(`length:${step}:${offset}`, key, () => this.lengthNow(key), (length) => length === void 0 ? void 0 : Math.ceil((length + offset) / step));
13594
+ }
13595
+ /**
13596
+ * Check a string against a decoded UTF-16 length limit without materializing it.
13597
+ * @param key - argument name.
13598
+ * @param maxLength - decoded UTF-16 limit, floored to at least zero.
13599
+ * @returns whether the string is longer than the limit; false when absent or not a string.
13600
+ */
13601
+ stringExceeds(key, maxLength) {
13602
+ const limit = Math.max(0, Math.floor(maxLength));
13603
+ return this.remember(`exceeds:${limit}`, key, () => (this.lengthNow(key, limit + 1) ?? 0) > limit);
13604
+ }
13605
+ /**
13606
+ * Read a decoded string, including a streaming prefix.
13607
+ * @param key - argument name.
13608
+ * @returns the string field's decoded text so far; undefined when absent or not a string.
13609
+ */
13610
+ text(key) {
13611
+ return this.remember("text", key, () => this.textNow(key));
13612
+ }
13613
+ /**
13614
+ * Read at most the first decoded UTF-16 units of a string.
13615
+ * @param key - argument name.
13616
+ * @param maxLength - maximum decoded UTF-16 length, floored to at least one.
13617
+ * @returns the bounded string prefix; undefined when absent or not a string.
13618
+ */
13619
+ textPrefix(key, maxLength) {
13620
+ const limit = Math.max(1, Math.floor(maxLength));
13621
+ return this.remember(`prefix:${limit}`, key, () => this.textPrefixNow(key, limit));
13622
+ }
13623
+ /**
13624
+ * Read a completed non-string argument.
13625
+ * @param key - argument name.
13626
+ * @returns the parsed non-string value once it closed; undefined while open, absent, or a string.
13627
+ */
13628
+ value(key) {
13629
+ return this.remember("value", key, () => this.valueNow(key));
13630
+ }
13631
+ /** Answer a question and, on a streaming view, remember it for change detection. */
13632
+ remember(kind, key, read, comparison) {
13633
+ this.scan();
13634
+ const result = read();
13635
+ if (!this.sealed) {
13636
+ const id = `${kind}/${key}`;
13637
+ if (!this.#reads.has(id)) this.#reads.set(id, {
13638
+ completion: kind === "complete",
13639
+ answer: comparison === void 0 ? read : () => comparison(read()),
13640
+ last: comparison === void 0 ? result : comparison(result)
13641
+ });
13642
+ }
13643
+ return result;
13644
+ }
13645
+ closedNow() {
13646
+ return this.sealed || this.#mode === "closed" || this.#mode === "invalid";
13647
+ }
13648
+ keysNow() {
13649
+ return this.object === void 0 ? this.#order : Object.keys(this.object);
13650
+ }
13651
+ hasNow(key) {
13652
+ return this.object === void 0 ? this.#entries.has(key) : Object.hasOwn(this.object, key);
13653
+ }
13654
+ completeNow(key) {
13655
+ if (this.object !== void 0) return Object.hasOwn(this.object, key);
13656
+ const entry = this.#entries.get(key);
13657
+ return entry !== void 0 && entry.end >= 0 && (entry.kind === "string" ? entry.invalidAt === void 0 : !entry.invalid);
13658
+ }
13659
+ lengthNow(key, limit = Number.POSITIVE_INFINITY) {
13660
+ if (this.object !== void 0) {
13661
+ const field = Object.hasOwn(this.object, key) ? this.object[key] : void 0;
13662
+ return typeof field === "string" ? field.length : void 0;
13663
+ }
13664
+ const entry = this.#entries.get(key);
13665
+ if (entry?.kind !== "string") return void 0;
13666
+ if (entry.text !== void 0 && entry.text.at === entry.end) return entry.text.length;
13667
+ const read = entry.length ??= {
13668
+ at: entry.start,
13669
+ length: 0,
13670
+ text: ""
13671
+ };
13672
+ this.readString(entry, read, limit, false);
13673
+ return read.length;
13674
+ }
13675
+ textNow(key) {
13676
+ if (this.object !== void 0) {
13677
+ const field = Object.hasOwn(this.object, key) ? this.object[key] : void 0;
13678
+ return typeof field === "string" ? field : void 0;
13679
+ }
13680
+ const entry = this.#entries.get(key);
13681
+ if (entry?.kind !== "string") return void 0;
13682
+ if (entry.text === void 0 && entry.end >= 0 && entry.needsDecoding && entry.invalidAt === void 0) {
13683
+ let text;
13684
+ try {
13685
+ text = JSON.parse(`"${this.slice(entry.start, entry.end)}"`);
13686
+ } catch (_error) {}
13687
+ if (text !== void 0) entry.text = {
13688
+ at: entry.end,
13689
+ length: text.length,
13690
+ text
13691
+ };
13692
+ }
13693
+ const read = entry.text ??= {
13694
+ at: entry.start,
13695
+ length: 0,
13696
+ text: ""
13697
+ };
13698
+ this.readString(entry, read, Number.POSITIVE_INFINITY, true);
13699
+ return read.text;
13700
+ }
13701
+ textPrefixNow(key, maxLength) {
13702
+ if (this.object !== void 0) {
13703
+ const field = Object.hasOwn(this.object, key) ? this.object[key] : void 0;
13704
+ return typeof field === "string" ? field.slice(0, maxLength) : void 0;
13705
+ }
13706
+ const entry = this.#entries.get(key);
13707
+ if (entry?.kind !== "string") return void 0;
13708
+ const prefixes = entry.prefixes ??= /* @__PURE__ */ new Map();
13709
+ let read = prefixes.get(maxLength);
13710
+ if (read === void 0) {
13711
+ read = {
13712
+ at: entry.start,
13713
+ length: 0,
13714
+ text: ""
13715
+ };
13716
+ prefixes.set(maxLength, read);
13717
+ }
13718
+ this.readString(entry, read, maxLength, true);
13719
+ return read.text;
13720
+ }
13721
+ valueNow(key) {
13722
+ if (this.object !== void 0) {
13723
+ if (!Object.hasOwn(this.object, key)) return void 0;
13724
+ const field = this.object[key];
13725
+ return typeof field === "string" ? void 0 : field;
13726
+ }
13727
+ const entry = this.#entries.get(key);
13728
+ if (entry?.kind !== "value" || entry.end < 0 || entry.invalid) return void 0;
13729
+ if (entry.parsed === void 0) try {
13730
+ entry.parsed = JSON.parse(this.slice(entry.start, entry.end));
13731
+ } catch (_error) {
13732
+ entry.invalid = true;
13733
+ this.#invalidValue = true;
13734
+ }
13735
+ return entry.parsed;
13736
+ }
13737
+ chunkAt(at) {
13738
+ let low = 0;
13739
+ let high = this.#ends.length;
13740
+ while (low < high) {
13741
+ const mid = low + high >>> 1;
13742
+ if (this.#ends[mid] <= at) low = mid + 1;
13743
+ else high = mid;
13744
+ }
13745
+ return low;
13746
+ }
13747
+ /** Materialize only a requested range, never the cumulative source. */
13748
+ slice(start, end) {
13749
+ if (start >= end) return "";
13750
+ const first = this.chunkAt(start);
13751
+ const last = this.chunkAt(end - 1);
13752
+ const base = first === 0 ? 0 : this.#ends[first - 1];
13753
+ if (first === last) return this.chunks[first].slice(start - base, end - base);
13754
+ const parts = [this.chunks[first].slice(start - base)];
13755
+ for (let i = first + 1; i < last; i++) parts.push(this.chunks[i]);
13756
+ parts.push(this.chunks[last].slice(0, end - this.#ends[last - 1]));
13757
+ return parts.join("");
13758
+ }
13759
+ readString(entry, read, limit, materialize) {
13760
+ const end = Math.min(entry.end < 0 ? this.#consumed : entry.end, entry.invalidAt ?? Number.POSITIVE_INFINITY, this.#invalidAt ?? Number.POSITIVE_INFINITY);
13761
+ if (!entry.needsDecoding) {
13762
+ const length = Math.min(end - read.at, limit - read.length);
13763
+ if (length <= 0) return;
13764
+ if (materialize) read.text += this.slice(read.at, read.at + length);
13765
+ read.at += length;
13766
+ read.length += length;
13767
+ return;
13768
+ }
13769
+ let chunkIndex = this.chunkAt(read.at);
13770
+ while (read.at < end && read.length < limit) {
13771
+ const base = chunkIndex === 0 ? 0 : this.#ends[chunkIndex - 1];
13772
+ const chunk = this.chunks[chunkIndex];
13773
+ const remaining = chunk.slice(read.at - base, Math.min(chunk.length, end - base));
13774
+ const boundary = remaining.search(CONTENT_ESCAPE);
13775
+ const length = Math.min(boundary < 0 ? remaining.length : boundary, limit - read.length);
13776
+ if (length > 0) {
13777
+ if (materialize) read.text += remaining.slice(0, length);
13778
+ read.at += length;
13779
+ read.length += length;
13780
+ if (read.at === base + chunk.length) chunkIndex++;
13781
+ continue;
13782
+ }
13783
+ const type = remaining.length > 1 ? remaining[1] : read.at + 1 < end ? this.chunks[chunkIndex + 1][0] : void 0;
13784
+ let decoded;
13785
+ let width = 2;
13786
+ if (remaining[0] === "\\" && type === void 0 && entry.end < 0) return;
13787
+ if (remaining[0] === "\\" && type === "u") {
13788
+ const hex = this.slice(read.at + 2, Math.min(end, read.at + 6));
13789
+ let valid = true;
13790
+ for (let i = 0; i < hex.length; i++) if (!isHex(hex[i])) valid = false;
13791
+ if (valid) {
13792
+ if (hex.length < 4 && entry.end < 0) return;
13793
+ if (hex.length === 4) decoded = String.fromCharCode(Number.parseInt(hex, 16));
13794
+ }
13795
+ width = 6;
13796
+ } else if (remaining[0] === "\\" && type !== void 0) decoded = SIMPLE_ESCAPES[type];
13797
+ if (decoded === void 0) {
13798
+ entry.invalidAt = read.at;
13799
+ this.#invalidValue = true;
13800
+ return;
13801
+ }
13802
+ if (materialize) read.text += decoded;
13803
+ read.length++;
13804
+ read.at += width;
13805
+ while (chunkIndex < this.chunks.length && read.at >= this.#ends[chunkIndex]) chunkIndex++;
13806
+ }
13807
+ }
13808
+ /** Locate new field ranges without decoding or parsing their contents. */
13809
+ scan() {
13810
+ if (this.object !== void 0 || this.#consumed === this.#size) return;
13811
+ for (let i = this.chunkAt(this.#consumed); i < this.chunks.length && this.#invalidAt === void 0; i++) {
13812
+ const pending = this.chunks[i];
13813
+ const base = i === 0 ? 0 : this.#ends[i - 1];
13814
+ for (let index = this.#consumed - base; index < pending.length && this.#mode !== "invalid"; index++) {
13815
+ if (this.#mode === "string" || this.#mode === "nested" && this.#nestedInString) {
13816
+ const end = this.stringBoundary(pending, index);
13817
+ this.#consumed += end - index;
13818
+ index = end;
13819
+ if (index === pending.length) break;
13820
+ }
13821
+ this.step(pending[index], this.#consumed);
13822
+ this.#consumed++;
13823
+ }
13824
+ }
13825
+ }
13826
+ /** Only raw quotes and their preceding backslash runs can terminate a string. */
13827
+ stringBoundary(fragment, start) {
13828
+ let at = start;
13829
+ while (true) {
13830
+ const quote = fragment.indexOf("\"", at);
13831
+ const end = quote < 0 ? fragment.length : quote;
13832
+ if (this.#mode === "string") {
13833
+ const entry = this.#current;
13834
+ if (!entry.needsDecoding && CONTENT_ESCAPE.test(fragment.slice(at, end))) entry.needsDecoding = true;
13835
+ }
13836
+ let slashStart = end;
13837
+ while (slashStart > at && fragment[slashStart - 1] === "\\") slashStart--;
13838
+ const escaped = (end - slashStart) % 2 === 1 !== (slashStart === at && this.#escape);
13839
+ this.#escape = quote < 0 && escaped;
13840
+ if (quote < 0 || !escaped) return end;
13841
+ at = quote + 1;
13842
+ }
13843
+ }
13844
+ step(c, at) {
13845
+ switch (this.#mode) {
13846
+ case "root":
13847
+ if (isWhitespace(c)) return;
13848
+ if (c === "{") {
13849
+ this.#mode = "key-or-end";
13850
+ return;
13851
+ }
13852
+ this.fail();
13853
+ return;
13854
+ case "key-or-end":
13855
+ if (isWhitespace(c)) return;
13856
+ if (c === "}") {
13857
+ this.#mode = "closed";
13858
+ return;
13859
+ }
13860
+ if (c === "\"") {
13861
+ this.beginKey(at);
13862
+ return;
13863
+ }
13864
+ this.fail();
13865
+ return;
13866
+ case "key-only":
13867
+ if (isWhitespace(c)) return;
13868
+ if (c === "\"") {
13869
+ this.beginKey(at);
13870
+ return;
13871
+ }
13872
+ this.fail();
13873
+ return;
13874
+ case "key":
13875
+ this.stepKey(c, at);
13876
+ return;
13877
+ case "colon":
13878
+ if (isWhitespace(c)) return;
13879
+ if (c === ":") {
13880
+ this.#mode = "value";
13881
+ return;
13882
+ }
13883
+ this.fail();
13884
+ return;
13885
+ case "value":
13886
+ this.beginValue(c, at);
13887
+ return;
13888
+ case "string": {
13889
+ const entry = this.#current;
13890
+ entry.end = at;
13891
+ this.#current = null;
13892
+ this.#mode = "comma-or-end";
13893
+ return;
13894
+ }
13895
+ case "scalar":
13896
+ this.stepScalar(c, at);
13897
+ return;
13898
+ case "nested":
13899
+ this.stepNested(c, at);
13900
+ return;
13901
+ case "comma-or-end":
13902
+ if (isWhitespace(c)) return;
13903
+ if (c === ",") {
13904
+ this.#mode = "key-only";
13905
+ return;
13906
+ }
13907
+ if (c === "}") {
13908
+ this.#mode = "closed";
13909
+ return;
13910
+ }
13911
+ this.fail();
13912
+ return;
13913
+ case "closed":
13914
+ if (isWhitespace(c)) return;
13915
+ this.fail();
13916
+ return;
13917
+ case "invalid": return;
13918
+ default: assertNever$1(this.#mode);
13919
+ }
13920
+ }
13921
+ fail() {
13922
+ this.#invalidAt = this.#consumed;
13923
+ this.#mode = "invalid";
13924
+ this.#current = null;
13925
+ }
13926
+ beginKey(at) {
13927
+ this.#mode = "key";
13928
+ this.#keyStart = at + 1;
13929
+ this.#keyEscaped = false;
13930
+ this.#escape = false;
13931
+ }
13932
+ stepKey(c, at) {
13933
+ if (c < " ") {
13934
+ this.fail();
13935
+ return;
13936
+ }
13937
+ if (this.#escape) {
13938
+ this.#escape = false;
13939
+ return;
13940
+ }
13941
+ if (c === "\\") {
13942
+ this.#escape = true;
13943
+ this.#keyEscaped = true;
13944
+ return;
13945
+ }
13946
+ if (c !== "\"") return;
13947
+ const raw = this.slice(this.#keyStart, at);
13948
+ if (this.#keyEscaped) try {
13949
+ this.#key = JSON.parse(`"${raw}"`);
13950
+ } catch (_error) {
13951
+ this.fail();
13952
+ return;
13953
+ }
13954
+ else this.#key = raw;
13955
+ this.#mode = "colon";
13956
+ }
13957
+ open(entry) {
13958
+ if (!this.#entries.has(this.#key)) this.#order.push(this.#key);
13959
+ this.#entries.set(this.#key, entry);
13960
+ this.#current = entry;
13961
+ }
13962
+ beginValue(c, at) {
13963
+ if (isWhitespace(c)) return;
13964
+ if (c === "\"") {
13965
+ this.open({
13966
+ kind: "string",
13967
+ start: at + 1,
13968
+ end: -1,
13969
+ needsDecoding: false,
13970
+ invalidAt: void 0,
13971
+ length: void 0,
13972
+ text: void 0,
13973
+ prefixes: void 0
13974
+ });
13975
+ this.#escape = false;
13976
+ this.#mode = "string";
13977
+ return;
13978
+ }
13979
+ if (c === "}" || c === "," || c === ":" || c === "]") {
13980
+ this.fail();
13981
+ return;
13982
+ }
13983
+ this.open({
13984
+ kind: "value",
13985
+ start: at,
13986
+ end: -1,
13987
+ parsed: void 0,
13988
+ invalid: false
13989
+ });
13990
+ if (c === "{" || c === "[") {
13991
+ this.#mode = "nested";
13992
+ this.#nestedEnds = [c === "{" ? "}" : "]"];
13993
+ this.#nestedInString = false;
13994
+ this.#escape = false;
13995
+ return;
13996
+ }
13997
+ this.#mode = "scalar";
13998
+ }
13999
+ stepScalar(c, at) {
14000
+ if (c !== "," && c !== "}" && !isWhitespace(c)) return;
14001
+ this.closeValue(at);
14002
+ this.#mode = c === "," ? "key-only" : c === "}" ? "closed" : "comma-or-end";
14003
+ }
14004
+ stepNested(c, at) {
14005
+ if (this.#nestedInString) {
14006
+ this.#nestedInString = false;
14007
+ return;
14008
+ }
14009
+ if (c === "\"") {
14010
+ this.#nestedInString = true;
14011
+ return;
14012
+ }
14013
+ if (c === "{" || c === "[") {
14014
+ this.#nestedEnds.push(c === "{" ? "}" : "]");
14015
+ return;
14016
+ }
14017
+ if (c === "}" || c === "]") {
14018
+ if (this.#nestedEnds.pop() !== c) {
14019
+ this.fail();
14020
+ return;
14021
+ }
14022
+ if (this.#nestedEnds.length === 0) {
14023
+ this.closeValue(at + 1);
14024
+ this.#mode = "comma-or-end";
14025
+ }
14026
+ }
14027
+ }
14028
+ closeValue(end) {
14029
+ const entry = this.#current;
14030
+ entry.end = end;
14031
+ this.#current = null;
14032
+ }
14033
+ });
14034
+ /**
14035
+ * Mark an unreachable closed-union branch.
14036
+ * @param value - impossible value; an unhandled typed variant fails at the call site.
14037
+ * @param context - optional switch-site label included in the failure message.
14038
+ * @returns never; a runtime value that escaped its type always throws.
14039
+ */
14040
+ function assertNever$1(value, context) {
14041
+ const rendered = JSON.stringify(value) ?? String(value);
14042
+ throw new Error(`unreachable variant${context ? ` in ${context}` : ""}: ${rendered}`);
14043
+ }
14044
+ /** Whether a path uses a Windows drive or UNC prefix. */
13227
14045
  function isWindowsStylePath(value) {
13228
14046
  return /^[A-Za-z]:[/\\]/.test(value) || value.startsWith("\\\\");
13229
14047
  }
@@ -13760,6 +14578,7 @@ const official$2 = ((require$1) => {
13760
14578
  sessions;
13761
14579
  view;
13762
14580
  notify;
14581
+ /** The latest in-flight connection per Workspace; a request joins it only when both name the same preset. */
13763
14582
  connecting = /* @__PURE__ */ new Map();
13764
14583
  lifetime = new AbortController();
13765
14584
  selection = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({}, { persist: { name: "dsh.sessions.current" } });
@@ -13774,6 +14593,7 @@ const official$2 = ((require$1) => {
13774
14593
  */
13775
14594
  constructor(ctx, directoryPicker, workspaces, sessions, view, notify) {
13776
14595
  super(ctx, "uiWorkspace");
14596
+ this.managedWorktreeGuard = ctx.get("__dshGitWorktreeManagedGuard");
13777
14597
  this.directoryPicker = directoryPicker;
13778
14598
  this.workspaces = workspaces;
13779
14599
  this.sessions = sessions;
@@ -13790,46 +14610,90 @@ const official$2 = ((require$1) => {
13790
14610
  };
13791
14611
  }, "ui-workspace: Workspace navigation policy");
13792
14612
  }
13793
- async connectWorkspace(workspaceId) {
14613
+ connectWorkspace(workspaceId, options = {}) {
14614
+ return this.connectBlank(workspaceId, options);
14615
+ }
14616
+ /**
14617
+ * @param reuse - preset for the reused or created blank; absent creates a fresh Session.
14618
+ */
14619
+ async connectBlank(workspaceId, reuse) {
13794
14620
  const workspace = this.workspaces.list.getSnapshot().items.find((item) => item.workspaceId === workspaceId);
13795
14621
  if (workspace === void 0) throw new Error(`uiWorkspace.connectWorkspace: unknown workspace ${workspaceId}`);
14622
+ if (reuse === void 0) return this.sessions.create({ workspaceId });
13796
14623
  const inflight = this.connecting.get(workspaceId);
13797
- if (inflight !== void 0) return inflight;
13798
- const attempt$1 = this.reuseOrCreateBlank(workspace).finally(() => {
13799
- this.connecting.delete(workspaceId);
14624
+ if (inflight !== void 0 && inflight.agentPreset === reuse.agentPreset) return inflight.attempt;
14625
+ const attempt$1 = this.createInWorkspace(workspace, reuse).finally(() => {
14626
+ if (this.connecting.get(workspaceId)?.attempt === attempt$1) this.connecting.delete(workspaceId);
14627
+ });
14628
+ this.connecting.set(workspaceId, {
14629
+ agentPreset: reuse.agentPreset,
14630
+ attempt: attempt$1
13800
14631
  });
13801
- this.connecting.set(workspaceId, attempt$1);
13802
14632
  return attempt$1;
13803
14633
  }
13804
- reuseOrCreateBlank(workspace) {
14634
+ createInWorkspace(workspace, options) {
13805
14635
  const archived = this.workspaces.list.getSnapshot().archivedSessionIds;
13806
14636
  const sessions = this.sessions.list.getSnapshot();
13807
- for (const id of sessions.ids) {
14637
+ const blank = sessions.ids.find((id) => {
13808
14638
  const summary = sessions.byId[id];
13809
- if (summary === void 0 || !summary.blank || summary.cwd !== workspace.path || !workspace.sessionIds.includes(id) || archived.includes(id)) continue;
13810
- return this.reuseBlank(workspace.workspaceId, id);
13811
- }
13812
- return this.sessions.create({ workspaceId: workspace.workspaceId });
14639
+ return summary !== void 0 && summary.blank && summary.cwd === workspace.path && workspace.sessionIds.includes(id) && !archived.includes(id);
14640
+ });
14641
+ return this.createNamed({
14642
+ workspaceId: workspace.workspaceId,
14643
+ ...blank === void 0 ? {} : { sessionId: blank },
14644
+ ...options.agentPreset === void 0 ? {} : { agentPreset: options.agentPreset }
14645
+ });
13813
14646
  }
13814
- async reuseBlank(workspaceId, sessionId) {
14647
+ /**
14648
+ * Create through the Host. A named blank the Host declined may still read as
14649
+ * blank from stale cached list metadata, which hides it from the Session tree;
14650
+ * its projections are reloaded so the row reflects its log.
14651
+ */
14652
+ async createNamed(request) {
14653
+ const sessionId = await this.sessions.create(request);
14654
+ const named = request.sessionId;
14655
+ if (named !== void 0 && named !== sessionId) this.sessions.refreshProjections(named).catch((reason) => {
14656
+ console.warn("declined blank Session projection reload failed:", reason);
14657
+ });
14658
+ return sessionId;
14659
+ }
14660
+ /**
14661
+ * Reopen a saved blank Session under the preset its log recorded, or under
14662
+ * the Host default once that preset no longer activates. Listed values are
14663
+ * cached hints that can lag the log after an unclean Host exit, so the
14664
+ * Session's projections are reloaded before the preset is read; a Session
14665
+ * that still awaits a format migration reloads only those cached hints.
14666
+ */
14667
+ async restoreBlank(workspaceId, sessionId) {
14668
+ await this.sessions.refreshProjections(sessionId);
14669
+ const recorded = this.sessions.list.getSnapshot().byId[sessionId]?.projectionValues?.agentPreset;
14670
+ const request = {
14671
+ workspaceId,
14672
+ sessionId
14673
+ };
14674
+ if (typeof recorded !== "string") return this.createNamed(request);
13815
14675
  try {
13816
- return await this.sessions.create({
13817
- workspaceId,
13818
- sessionId
14676
+ return await this.createNamed({
14677
+ ...request,
14678
+ agentPreset: recorded
13819
14679
  });
13820
14680
  } catch (error) {
13821
- if (sessionCreateErrorOf(error)?.rpcError.code !== "session/writer-held") throw error;
13822
- return this.sessions.create({ workspaceId });
14681
+ const code = sessionCreateErrorOf(error)?.rpcError.code;
14682
+ if (code !== "agent-preset/not-found" && code !== "agent-preset/invalid") throw error;
14683
+ return this.createNamed(request);
13823
14684
  }
13824
14685
  }
13825
14686
  openSession(target) {
13826
14687
  this.replaceMain(target, this.lifetime.signal, "reveal");
13827
14688
  }
13828
- async openWorkspace(workspaceId, beforeOpen) {
14689
+ openWorkspace(workspaceId, beforeOpen, options = {}) {
14690
+ return this.openWorkspaceSession(workspaceId, beforeOpen, options);
14691
+ }
14692
+ async openWorkspaceSession(workspaceId, beforeOpen, reuse) {
13829
14693
  const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]);
13830
14694
  let sessionId;
13831
14695
  try {
13832
- sessionId = await this.connectWorkspace(workspaceId);
14696
+ sessionId = await this.connectBlank(workspaceId, reuse);
13833
14697
  } catch (error) {
13834
14698
  if (!navigation.aborted) this.notify({
13835
14699
  kind: "createFailed",
@@ -13840,28 +14704,58 @@ const official$2 = ((require$1) => {
13840
14704
  if (navigation.aborted) return;
13841
14705
  this.replaceMain(sessionId, navigation, "reveal", beforeOpen);
13842
14706
  }
13843
- async forkSession(sessionId, onCreated) {
14707
+ async forkSession(sessionId, onCreated, options) {
14708
+ if (this.managedWorktreeGuard.blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
13844
14709
  return this.sessions.fork({
13845
14710
  sessionId,
13846
14711
  increaseTitle: true,
13847
- ...onCreated === void 0 ? {} : { onCreated }
14712
+ ...onCreated === void 0 ? {} : { onCreated },
14713
+ ...options?.allowMigration === void 0 ? {} : { allowMigration: options.allowMigration }
13848
14714
  });
13849
14715
  }
13850
- startSession(workspaceId) {
14716
+ startSession(workspaceId, options) {
14717
+ const { agentPreset, ...draft } = options ?? {};
14718
+ const draftOptions = options === void 0 ? void 0 : draft;
14719
+ const initializeDraft = draftOptions !== void 0 && (draftOptions.prompt !== void 0 || draftOptions.clearPreviousDraft === true);
13851
14720
  const workspace = this.workspaces.list.getSnapshot();
13852
14721
  const sessions = this.sessions.list.getSnapshot();
13853
14722
  const current = this.mainReference?.sessionId;
13854
14723
  const currentWorkspaceId = current === void 0 ? void 0 : workspace.items.find((item) => item.sessionIds.includes(current))?.workspaceId;
13855
14724
  const recent = workspace.phase === "ready" && sessions.phase === "ready" ? recentWorkspace(workspace.items, sessions.byId) : void 0;
13856
14725
  const target = workspaceId ?? currentWorkspaceId ?? recent;
14726
+ if (target !== void 0 && this.managedWorktreeGuard.blockWorkspace(target)) return;
13857
14727
  if (target === void 0) {
14728
+ if (initializeDraft) {
14729
+ this.notify({
14730
+ kind: "createFailed",
14731
+ message: this.ctx.locale.bind("workspace")("draft.workspaceRequired")
14732
+ });
14733
+ return;
14734
+ }
13858
14735
  this.clearMain();
13859
14736
  return;
13860
14737
  }
13861
- this.openWorkspace(target).catch((reason) => {
14738
+ (draftOptions === void 0 ? this.openWorkspaceSession(target, void 0, void 0) : this.openWorkspace(target, initializeDraft ? (id) => {
14739
+ const binding = this.sessions.binding(id);
14740
+ if (binding === void 0) this.draftPreparationFailed();
14741
+ this.prepareDraft(binding, draftOptions);
14742
+ } : void 0, agentPreset === void 0 ? {} : { agentPreset })).catch((reason) => {
13862
14743
  console.warn("new session failed:", reason);
13863
14744
  });
13864
14745
  }
14746
+ prepareDraft(binding, options) {
14747
+ const conversation = this.ctx.get("conversation");
14748
+ if (conversation === void 0) this.draftPreparationFailed();
14749
+ if (conversation.input.requestDraftInitialization(binding, options) === "blocked") this.draftPreparationFailed();
14750
+ }
14751
+ draftPreparationFailed() {
14752
+ const message = this.ctx.locale.bind("workspace")("draft.initializationFailed");
14753
+ this.notify({
14754
+ kind: "createFailed",
14755
+ message
14756
+ });
14757
+ throw new Error(message);
14758
+ }
13865
14759
  async archiveSession(sessionId, options = {}) {
13866
14760
  await this.workspaces.archiveSession(sessionId, options);
13867
14761
  if (this.mainReference?.sessionId === sessionId) this.clearMain();
@@ -13940,7 +14834,7 @@ const official$2 = ((require$1) => {
13940
14834
  }
13941
14835
  const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]);
13942
14836
  let sessionId;
13943
- if (summary !== void 0 && workspace !== void 0 && summary.cwd === workspace.path && !workspaces.archivedSessionIds.includes(summary.id)) sessionId = await this.reuseBlank(workspace.workspaceId, summary.id);
14837
+ if (summary !== void 0 && workspace !== void 0 && summary.cwd === workspace.path && !workspaces.archivedSessionIds.includes(summary.id)) sessionId = await this.restoreBlank(workspace.workspaceId, summary.id);
13944
14838
  let target = workspace?.workspaceId ?? recentWorkspace(workspaces.items, sessions.byId);
13945
14839
  if (target === void 0 && workspaces.items.length === 0 && sessions.ids.length === 0) {
13946
14840
  const prepared = await this.initializeDefaultWorkspace(navigation);
@@ -14058,11 +14952,11 @@ const official$2 = ((require$1) => {
14058
14952
  function workspaceDisplayTitle(title, localizedDefault) {
14059
14953
  return title === "default-workspace" ? localizedDefault : title;
14060
14954
  }
14061
- const css$3 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{border-radius:var(--dsw-radius-md);padding:0 8px;cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);align-items:center;gap:6px;padding-inline-start:calc(8px + var(--dsh-workspace-indent,0px));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;border-radius:var(--dsw-radius-lg);cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--dsw-alias-label-primary);background:0 0;border:none;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_searchResultWorkspace:only-child{max-width:100%}.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{gap:0;height:32px}.YDXeBa_sessionRow .YDXeBa_title{margin:0 6px 0 4px}.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);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-button-elevated-fill);min-width:0;color:inherit;outline:none;padding:0 2px;font-size:14px;line-height:20px}.YDXeBa_sessionRow .YDXeBa_title{flex:1}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled]{mask-image:linear-gradient(90deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-clipped]{mask-image:linear-gradient(270deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled][data-clipped]{mask-image:linear-gradient(90deg,#0000,#000 12px calc(100% - 12px),#0000)}.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:10px;line-height:16px}.YDXeBa_pinIndicator{width:16px;height:20px;color:var(--dsw-alias-label-caption);flex:none;justify-content:center;align-items:center;margin-left:6px;display:inline-flex}.YDXeBa_sessionRow.YDXeBa_archived .YDXeBa_title,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultTitle,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultWorkspace,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultSnippet{color:var(--dsw-alias-label-caption)}.YDXeBa_dot{flex:none}.YDXeBa_rowActions{flex:none;align-items:center;gap:10px;display:none}.YDXeBa_projectRow:hover .YDXeBa_rowActions,.YDXeBa_sessionRow:hover .YDXeBa_rowActions,.YDXeBa_searchResultRow:hover .YDXeBa_rowActions,.YDXeBa_projectRow.YDXeBa_menuOpen .YDXeBa_rowActions,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_rowActions{display:inline-flex}.YDXeBa_searchResultHeading .YDXeBa_rowActions{margin-left:auto}.YDXeBa_sessionRow:hover .YDXeBa_time,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_time,.YDXeBa_sessionRow:hover .YDXeBa_pinIndicator,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_pinIndicator{display:none}@media (hover:hover){.YDXeBa_sessionRow:hover .YDXeBa_title,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_title{text-overflow:clip}}.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_hoverArchived svg{flex-shrink:0;margin:0 -4px}.YDXeBa_iconButton{border-radius:var(--dsw-radius-xs);cursor:pointer;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;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_arrow{transition:none;animation:none}}";
14062
- const tagId$3 = "@deepseek-ai/dsh-client-ui-workspace/Rows.module.css";
14955
+ const css$3 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{border-radius:var(--dsw-radius-md);padding:0 8px;cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);align-items:center;gap:6px;padding-inline-start:calc(8px + var(--dsh-workspace-indent,0px));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;border-radius:var(--dsw-radius-lg);cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--dsw-alias-label-primary);background:0 0;border:none;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_searchResultWorkspace:only-child{max-width:100%}.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{gap:0;height:32px}.YDXeBa_sessionRow .YDXeBa_title{margin:0 6px 0 4px}.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);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-button-elevated-fill);min-width:0;color:inherit;outline:none;padding:0 2px;font-size:14px;line-height:20px}.YDXeBa_sessionRow .YDXeBa_title{flex:1}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled]{mask-image:linear-gradient(90deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-clipped]{mask-image:linear-gradient(270deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled][data-clipped]{mask-image:linear-gradient(90deg,#0000,#000 12px calc(100% - 12px),#0000)}.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:10px;line-height:16px}.YDXeBa_pinIndicator{width:16px;height:20px;color:var(--dsw-alias-label-caption);flex:none;justify-content:center;align-items:center;margin-left:6px;display:inline-flex}.YDXeBa_sessionRow.YDXeBa_archived .YDXeBa_title,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultTitle,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultWorkspace,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultSnippet{color:var(--dsw-alias-label-caption)}.YDXeBa_dot{flex:none}.YDXeBa_rowActions{flex:none;align-items:center;gap:15px;display:none}.YDXeBa_projectRow:hover .YDXeBa_rowActions,.YDXeBa_sessionRow:hover .YDXeBa_rowActions,.YDXeBa_searchResultRow:hover .YDXeBa_rowActions,.YDXeBa_projectRow.YDXeBa_menuOpen .YDXeBa_rowActions,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_rowActions{display:inline-flex}.YDXeBa_searchResultHeading .YDXeBa_rowActions{margin-left:auto}.YDXeBa_sessionRow:hover .YDXeBa_time,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_time,.YDXeBa_sessionRow:hover .YDXeBa_pinIndicator,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_pinIndicator{display:none}@media (hover:hover){.YDXeBa_sessionRow:hover .YDXeBa_title,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_title{text-overflow:clip}}.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_hoverArchived svg{flex-shrink:0;margin:0 -4px}.YDXeBa_iconButton{border-radius:var(--dsw-radius-xs);cursor:pointer;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;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_arrow{transition:none;animation:none}}";
14956
+ const tagId$3 = "dsh-git-worktree/workspace-0.2.1-rc.2/Rows.module.css";
14063
14957
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
14064
14958
  const tag = document.createElement("style");
14065
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
14959
+ tag.dataset.plugin = "dsh-git-worktree";
14066
14960
  tag.dataset.pluginCss = tagId$3;
14067
14961
  tag.textContent = css$3;
14068
14962
  document.head.appendChild(tag);
@@ -14343,6 +15237,7 @@ const official$2 = ((require$1) => {
14343
15237
  side: "bottom",
14344
15238
  align: "end",
14345
15239
  delayMs: 500,
15240
+ portal: true,
14346
15241
  children: !protectedManagedWorkspace && (0, react_jsx_runtime$1.jsx)("button", {
14347
15242
  type: "button",
14348
15243
  className: Rows_module_css_default.iconButton,
@@ -14368,6 +15263,7 @@ const official$2 = ((require$1) => {
14368
15263
  t
14369
15264
  }),
14370
15265
  openDelayMs: 800,
15266
+ grouped: true,
14371
15267
  disabled: menuOpen,
14372
15268
  copyText: row.cwd,
14373
15269
  copyLabel: t("copy"),
@@ -14470,7 +15366,7 @@ const official$2 = ((require$1) => {
14470
15366
  "data-worktree-state": decoration.state,
14471
15367
  "aria-hidden": "true",
14472
15368
  children: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutlineRegular, {})
14473
- }), (0, react_jsx_runtime$1.jsx)("span", {
15369
+ }), decoration.state !== "working" && (0, react_jsx_runtime$1.jsx)("span", {
14474
15370
  className: "dsh-git-worktree-sidebar-badge",
14475
15371
  "data-worktree-state": decoration.state,
14476
15372
  "aria-hidden": "true",
@@ -14550,6 +15446,7 @@ const official$2 = ((require$1) => {
14550
15446
  side: "bottom",
14551
15447
  align: "end",
14552
15448
  delayMs: 500,
15449
+ portal: true,
14553
15450
  children: (0, react_jsx_runtime$1.jsx)("button", {
14554
15451
  type: "button",
14555
15452
  className: Rows_module_css_default.iconButton,
@@ -14709,6 +15606,7 @@ const official$2 = ((require$1) => {
14709
15606
  t
14710
15607
  }),
14711
15608
  openDelayMs: 800,
15609
+ grouped: true,
14712
15610
  disabled: menuOpen || drag?.active === true,
14713
15611
  copyText: row.blank || row.title === "" ? void 0 : row.title,
14714
15612
  copyLabel: t("copy"),
@@ -14716,10 +15614,10 @@ const official$2 = ((require$1) => {
14716
15614
  });
14717
15615
  }
14718
15616
  const css$2 = ".Qg_5Eq_exits{contain:strict;pointer-events:none;position:absolute;inset:0;overflow:clip}";
14719
- const tagId$2 = "@deepseek-ai/dsh-client-ui-workspace/AnimatedRows.module.css";
15617
+ const tagId$2 = "dsh-git-worktree/workspace-0.2.1-rc.2/AnimatedRows.module.css";
14720
15618
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
14721
15619
  const tag = document.createElement("style");
14722
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
15620
+ tag.dataset.plugin = "dsh-git-worktree";
14723
15621
  tag.dataset.pluginCss = tagId$2;
14724
15622
  tag.textContent = css$2;
14725
15623
  document.head.appendChild(tag);
@@ -14888,10 +15786,10 @@ const official$2 = ((require$1) => {
14888
15786
  }
14889
15787
  };
14890
15788
  const css$1 = "._G5b-a_modalAction{min-width:72px}._G5b-a_modalError,._G5b-a_menuStatus{margin-top:8px;font-size:12px;line-height:18px}._G5b-a_modalError{color:var(--dsw-alias-state-error-primary)}._G5b-a_menuStatus{color:var(--dsw-alias-label-secondary)}";
14891
- const tagId$1 = "@deepseek-ai/dsh-client-ui-workspace/WorkspacePicker.module.css";
15789
+ const tagId$1 = "dsh-git-worktree/workspace-0.2.1-rc.2/WorkspacePicker.module.css";
14892
15790
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
14893
15791
  const tag = document.createElement("style");
14894
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
15792
+ tag.dataset.plugin = "dsh-git-worktree";
14895
15793
  tag.dataset.pluginCss = tagId$1;
14896
15794
  tag.textContent = css$1;
14897
15795
  document.head.appendChild(tag);
@@ -15057,10 +15955,10 @@ const official$2 = ((require$1) => {
15057
15955
  });
15058
15956
  }
15059
15957
  const css = ".bhn1Oq_root{--dsh-session-list-edge-inset:var(--dsh-sidebar-inline-padding);--dsh-session-list-scrollbar-width:5px;--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{border-radius:var(--dsw-radius-sm);cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.bhn1Oq_iconButton:focus-visible,.bhn1Oq_searchButton:focus-visible,.bhn1Oq_clearButton:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}.bhn1Oq_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.bhn1Oq_viewOptionsMenu{min-width:200px}.bhn1Oq_sectionHeader{box-sizing:border-box;border-radius:var(--dsw-radius-md);height:36px;color:var(--dsw-alias-label-tertiary);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;border-radius:var(--dsw-radius-sm);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;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);border-radius:var(--dsw-radius-md);width:calc(100% + 4px);height:30px;color:var(--dsw-alias-label-caption);background:0 0;margin-inline:-2px;padding:0 4px 0 0}.bhn1Oq_searchButton{border-radius:var(--dsw-radius-sm);cursor:pointer;width:28px;height:28px;color:inherit;background:0 0;border:none;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{border-radius:var(--dsw-radius-sm);cursor:pointer;width:24px;height:24px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;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{border-radius:var(--dsw-radius-md);width:36px;height:36px;color:var(--dsw-alias-label-primary)}.bhn1Oq_rail .bhn1Oq_search{border-radius:var(--dsw-radius-md);background:0 0;border-color:#0000;gap:0;width:36px;height:36px;margin:0 0 12px;padding:0}.bhn1Oq_rail .bhn1Oq_searchButton{border-radius:var(--dsw-radius-md);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}[data-platform=darwin] .bhn1Oq_fade{display:none}.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{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:12px;line-height:18px}.bhn1Oq_skeletonRow{box-sizing:border-box;align-items:flex-start;gap:8px;min-height:48px;padding:6px 8px 7px;display:flex}.bhn1Oq_skeletonDot{corner-shape:round;border-radius:50%;flex:none;width:16px;height:16px}.bhn1Oq_skeletonBars{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.bhn1Oq_skeletonDot,.bhn1Oq_skeletonBar{background:var(--dsw-alias-bg-skeleton);animation:2s cubic-bezier(.36,0,.64,1) infinite bhn1Oq_search-skeleton}.bhn1Oq_skeletonBar{border-radius:var(--dsw-radius-xs);width:65%;height:16px}.bhn1Oq_skeletonBarWide{width:90%;height:13px}@keyframes bhn1Oq_search-skeleton{0%{opacity:1}40%{opacity:.6}80%,to{opacity:1}}.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{border-radius:var(--dsw-radius-sm);width:100%;height:28px;padding:0 12px 0 calc(28px + var(--dsh-workspace-indent,0px));cursor:pointer;text-align:left;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;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_emptyState{color:var(--dsw-alias-label-tertiary);flex-direction:column;align-items:center;gap:8px;margin-top:80px;padding:0 12px;font-size:13px;line-height:20px;display:flex}.bhn1Oq_emptyState>svg{color:var(--dsw-alias-label-caption);margin-bottom:4px}.bhn1Oq_emptyAction{cursor:pointer;color:var(--dsw-alias-link);background:0 0;border:none;padding:0;font-size:13px;line-height:20px}.bhn1Oq_renameInput{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);width:100%;height:44px;color:var(--dsw-alias-label-primary);background:0 0;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}.bhn1Oq_archiveActivity{color:var(--dsw-alias-label-primary);margin:0 0 8px;padding-left:18px;font-size:13px;line-height:20px}.bhn1Oq_archiveActivity li{overflow-wrap:anywhere}@media (prefers-reduced-motion:reduce){.bhn1Oq_wide,.bhn1Oq_skeletonDot,.bhn1Oq_skeletonBar{animation:none}.bhn1Oq_search,.bhn1Oq_sectionLabel,.bhn1Oq_searchSlot,.bhn1Oq_searchInput,.bhn1Oq_headerActions{transition:none}}";
15060
- const tagId = "@deepseek-ai/dsh-client-ui-workspace/WorkspaceBrowser.module.css";
15958
+ const tagId = "dsh-git-worktree/workspace-0.2.1-rc.2/WorkspaceBrowser.module.css";
15061
15959
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
15062
15960
  const tag = document.createElement("style");
15063
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
15961
+ tag.dataset.plugin = "dsh-git-worktree";
15064
15962
  tag.dataset.pluginCss = tagId;
15065
15963
  tag.textContent = css;
15066
15964
  document.head.appendChild(tag);
@@ -15137,22 +16035,46 @@ const official$2 = ((require$1) => {
15137
16035
  const SEARCH_DEBOUNCE_MS = 250;
15138
16036
  /** `session.search` wire bound, measured in JavaScript UTF-16 code units. */
15139
16037
  const SEARCH_QUERY_MAX_CODE_UNITS = 500;
15140
- /** Idle Session rows visible per Workspace before the local overflow control. */
15141
- const COLLAPSED_SESSION_LIMIT = 5;
15142
- /** Keep provisional and running rows outside the idle-session quota, including parents with running children. */
15143
- function collapsedSessionRows(sessions, limit = COLLAPSED_SESSION_LIMIT) {
15144
- let idleCount = 0;
16038
+ /** Non-blank Session rows visible per Workspace while no Session raises its watermark. */
16039
+ const SESSION_WATERMARK_BASE = 5;
16040
+ /** Highest watermark that attention-bearing Sessions raise automatically; Show more and search reveals may exceed it. */
16041
+ const SESSION_WATERMARK_AUTO_MAX = 50;
16042
+ /** Show the blank row plus the first `watermark` non-blank rows, in list order. */
16043
+ function watermarkRows(sessions, watermark) {
16044
+ let count = 0;
15145
16045
  const rows = sessions.filter((session) => {
15146
- if (session.blank || session.running || session.runningSubagentCount > 0) return true;
15147
- if (idleCount >= limit) return false;
15148
- idleCount += 1;
15149
- return true;
16046
+ if (session.blank) return true;
16047
+ count += 1;
16048
+ return count <= watermark;
15150
16049
  });
15151
16050
  return {
15152
16051
  rows,
15153
16052
  hiddenCount: sessions.length - rows.length
15154
16053
  };
15155
16054
  }
16055
+ /**
16056
+ * Smallest watermark that covers every non-blank row within the automatic maximum that is running, has a running
16057
+ * child, awaits the user, carries an unread completion, or is current, and the reveal target at any position.
16058
+ */
16059
+ function requiredWatermark(sessions, current, revealSessionId) {
16060
+ let index = 0;
16061
+ let required$1 = 0;
16062
+ for (const session of sessions) {
16063
+ if (session.blank) continue;
16064
+ index += 1;
16065
+ if (index <= SESSION_WATERMARK_AUTO_MAX && (session.running || session.runningSubagentCount > 0 || session.pendingInteraction !== void 0 || session.completed || session.id === current) || session.id === revealSessionId) required$1 = index;
16066
+ }
16067
+ return required$1;
16068
+ }
16069
+ /** Raise each listed group's watermark to its requirement; returns `marks` itself when nothing rises. */
16070
+ function raiseWatermarks(marks, required$1) {
16071
+ let raised = marks;
16072
+ for (const [key, watermark] of required$1) if (watermark > (raised[key] ?? SESSION_WATERMARK_BASE)) raised = {
16073
+ ...raised,
16074
+ [key]: watermark
16075
+ };
16076
+ return raised;
16077
+ }
15156
16078
  /** Keep controlled input and RPC payload inside the session.search wire contract. */
15157
16079
  function sanitizeSearchQuery(value) {
15158
16080
  const withoutNul = value.replaceAll("\0", "");
@@ -15333,13 +16255,14 @@ const official$2 = ((require$1) => {
15333
16255
  ]
15334
16256
  });
15335
16257
  }
15336
- /** The scrolling session tree; unmounting drops the sessions subscription and local row limits. */
16258
+ /** The scrolling session tree; unmounting drops the sessions subscription and the session watermarks. */
15337
16259
  function SessionTree({ list, useSessionStatus, startSession, open, workspaces, ungroupedSessionIds, rowState, onLeaveArchivedOnly, workspaceReady, animationResetKey, usePanelInfo, onRenameRequest, onDeleteRequest, onSessionRenameRequest, renderSlot, insertWorkspaceBefore, nestWorkspaces, groupExpansion, setGroupExpanded, setSessionOrder, home, t, revealSessionId, onSessionRevealed, shortcuts }) {
15338
16260
  const panelActive = usePanelInfo((info) => info.activePanelId !== null);
15339
16261
  const statuses = useSessionStatus((s) => s);
15340
16262
  const current = panelActive ? void 0 : Object.values(list.byId).find((session) => (session.retainedBy.mainView ?? 0) > 0)?.id;
15341
16263
  const revealGroup = revealSessionId === void 0 || !workspaceReady ? void 0 : owningGroupKey(workspaces, revealSessionId);
15342
- const [sessionLimits, setSessionLimits] = (0, react$1.useState)({});
16264
+ const [storedWatermarks, setStoredWatermarks] = (0, react$1.useState)({});
16265
+ const [watermarkMotionKey, setWatermarkMotionKey] = (0, react$1.useState)(0);
15343
16266
  const [drag, setDrag] = (0, react$1.useState)(null);
15344
16267
  const sessionDropCommitted = (0, react$1.useRef)(false);
15345
16268
  const [workspaceDrag, setWorkspaceDrag] = (0, react$1.useState)(null);
@@ -15397,20 +16320,24 @@ const official$2 = ((require$1) => {
15397
16320
  revealGroup,
15398
16321
  setGroupExpanded
15399
16322
  ]);
15400
- (0, react$1.useEffect)(() => {
15401
- if (revealSessionId === void 0 || revealGroup === void 0) return;
15402
- const group = groups.find((candidate) => candidate.key === revealGroup);
15403
- if (group === void 0 || !group.expanded || !group.sessions.some((row) => row.id === revealSessionId)) return;
15404
- if (collapsedSessionRows(group.sessions).rows.some((row) => row.id === revealSessionId)) return;
15405
- setSessionLimits((limits) => limits[revealGroup] === Infinity ? limits : {
15406
- ...limits,
15407
- [revealGroup]: Infinity
15408
- });
15409
- }, [
15410
- groups,
15411
- revealGroup,
15412
- revealSessionId
15413
- ]);
16323
+ const baselines = new Map(groups.map((group) => [group.key, Math.max(SESSION_WATERMARK_BASE, requiredWatermark(group.sessions, current, group.key === revealGroup ? revealSessionId : void 0))]));
16324
+ const foldedKeys = new Set(groups.filter((group) => !group.expanded).map((group) => group.key));
16325
+ const underFoldedAncestor = (key) => {
16326
+ for (let owner = parents.get(key); owner !== void 0; owner = parents.get(owner)) if (foldedKeys.has(owner)) return true;
16327
+ return false;
16328
+ };
16329
+ const requiredWatermarks = new Map([...baselines].filter(([key]) => !underFoldedAncestor(key)));
16330
+ const sessionWatermarks = raiseWatermarks(storedWatermarks, requiredWatermarks);
16331
+ if (sessionWatermarks !== storedWatermarks) setStoredWatermarks((marks) => raiseWatermarks(marks, requiredWatermarks));
16332
+ const dropWatermarks = (drop) => {
16333
+ if (!Object.keys(storedWatermarks).some(drop)) return;
16334
+ setStoredWatermarks((marks) => Object.fromEntries(Object.entries(marks).filter(([key]) => !drop(key))));
16335
+ setWatermarkMotionKey((key) => key + 1);
16336
+ };
16337
+ const withinGroup = (key, root) => {
16338
+ for (let owner = key; owner !== void 0; owner = parents.get(owner)) if (owner === root) return true;
16339
+ return false;
16340
+ };
15414
16341
  const now = Date.now();
15415
16342
  const commitSessionDrag = (activeDrag, over) => {
15416
16343
  if (sessionDropCommitted.current) return;
@@ -15421,7 +16348,7 @@ const official$2 = ((require$1) => {
15421
16348
  if (over.id === activeDrag.sessionId) return;
15422
16349
  const accountSessionIds = activeDrag.accountKey === "" ? ungroupedSessionIds : workspaces.find((workspace) => workspace.workspaceId === activeDrag.accountKey)?.sessionIds;
15423
16350
  if (accountSessionIds === void 0) return;
15424
- const renderedSessions = collapsedSessionRows(group.sessions, sessionLimits[group.key]).rows;
16351
+ const renderedSessions = watermarkRows(group.sessions, sessionWatermarks[group.key] ?? SESSION_WATERMARK_BASE).rows;
15425
16352
  const nextOrder = sessionDragOrder(accountSessionIds, renderedSessions, activeDrag, over);
15426
16353
  if (nextOrder !== void 0) setSessionOrder(activeDrag.accountKey, nextOrder);
15427
16354
  };
@@ -15461,8 +16388,9 @@ const official$2 = ((require$1) => {
15461
16388
  const workspaceId = group.workspaceId;
15462
16389
  const children = childrenByParent.get(group.key) ?? [];
15463
16390
  const compatibleDrag = workspaceDrag !== null && parents.get(workspaceDrag.workspaceId) === parents.get(group.key);
15464
- const collapsed = collapsedSessionRows(group.sessions);
15465
- const visible = collapsedSessionRows(group.sessions, sessionLimits[group.key]);
16391
+ const watermark = sessionWatermarks[group.key] ?? SESSION_WATERMARK_BASE;
16392
+ const collapsed = watermarkRows(group.sessions, baselines.get(group.key) ?? SESSION_WATERMARK_BASE);
16393
+ const visible = watermarkRows(group.sessions, watermark);
15466
16394
  const sessionsExpanded = visible.hiddenCount === 0;
15467
16395
  rowKeys.push(`workspace:${group.key}`);
15468
16396
  const childRows = group.expanded ? children.map((child) => renderGroup(child, depth + 1)) : [];
@@ -15534,10 +16462,7 @@ const official$2 = ((require$1) => {
15534
16462
  home,
15535
16463
  t,
15536
16464
  onToggle: () => {
15537
- if (group.expanded) setSessionLimits((limits) => ({
15538
- ...limits,
15539
- [group.key]: COLLAPSED_SESSION_LIMIT
15540
- }));
16465
+ if (group.expanded) dropWatermarks((key) => withinGroup(key, group.key));
15541
16466
  setGroupExpanded(group.key, !group.expanded);
15542
16467
  },
15543
16468
  onCreate: () => {
@@ -15622,10 +16547,15 @@ const official$2 = ((require$1) => {
15622
16547
  "data-row-key": `overflow:${group.key}`,
15623
16548
  "aria-expanded": sessionsExpanded,
15624
16549
  onClick: () => {
15625
- setSessionLimits((limits) => ({
15626
- ...limits,
15627
- [group.key]: sessionsExpanded ? COLLAPSED_SESSION_LIMIT : visible.hiddenCount <= COLLAPSED_SESSION_LIMIT ? Infinity : (limits[group.key] ?? COLLAPSED_SESSION_LIMIT) + COLLAPSED_SESSION_LIMIT
16550
+ if (sessionsExpanded) {
16551
+ dropWatermarks((key) => key === group.key);
16552
+ return;
16553
+ }
16554
+ setStoredWatermarks((marks) => ({
16555
+ ...marks,
16556
+ [group.key]: visible.hiddenCount <= SESSION_WATERMARK_BASE ? Infinity : watermark + SESSION_WATERMARK_BASE
15628
16557
  }));
16558
+ setWatermarkMotionKey((key) => key + 1);
15629
16559
  },
15630
16560
  children: sessionsExpanded ? t("sessions.collapse") : t("sessions.expand", { n: visible.hiddenCount })
15631
16561
  })
@@ -15633,7 +16563,7 @@ const official$2 = ((require$1) => {
15633
16563
  }, group.key);
15634
16564
  };
15635
16565
  const groupRows = rootGroups.map((group) => renderGroup(group, 0));
15636
- return (0, react_jsx_runtime$1.jsxs)("div", {
16566
+ return (0, react_jsx_runtime$1.jsxs)(_deepseek_ai_dsh_client_ui_primitives.HoverCardGroup, {
15637
16567
  className: clsx(WorkspaceBrowser_module_css_default.treeBody, WorkspaceBrowser_module_css_default.wide),
15638
16568
  children: [
15639
16569
  workspaceDropAtListStart && (0, react_jsx_runtime$1.jsx)("span", {
@@ -15645,7 +16575,7 @@ const official$2 = ((require$1) => {
15645
16575
  label: t("section.sessions"),
15646
16576
  rowKeys,
15647
16577
  ready: list.phase === "ready" && workspaceReady && !nativeDragActive,
15648
- resetKey: JSON.stringify([animationResetKey, sessionLimits]),
16578
+ resetKey: JSON.stringify([animationResetKey, watermarkMotionKey]),
15649
16579
  children: [groups.length === 0 && (0, react_jsx_runtime$1.jsx)(EmptySessions, {
15650
16580
  rowState,
15651
16581
  onLeaveArchivedOnly,
@@ -15678,7 +16608,7 @@ const official$2 = ((require$1) => {
15678
16608
  if (nextOrder !== void 0) setSessionOrder(FLAT_SESSION_ORDER_KEY, nextOrder);
15679
16609
  };
15680
16610
  const now = Date.now();
15681
- return (0, react_jsx_runtime$1.jsxs)("div", {
16611
+ return (0, react_jsx_runtime$1.jsxs)(_deepseek_ai_dsh_client_ui_primitives.HoverCardGroup, {
15682
16612
  className: clsx(WorkspaceBrowser_module_css_default.treeBody, WorkspaceBrowser_module_css_default.wide),
15683
16613
  children: [(0, react_jsx_runtime$1.jsxs)(AnimatedRows, {
15684
16614
  className: clsx(WorkspaceBrowser_module_css_default.list, WorkspaceBrowser_module_css_default.flatList),
@@ -15811,7 +16741,7 @@ const official$2 = ((require$1) => {
15811
16741
  * @param props - composed slot props (shell owner share + store + injected actions).
15812
16742
  * @returns the region element tree.
15813
16743
  */
15814
- function WorkspaceBrowser({ wide, usePanelInfo, expandSidebar, useSessions, useSessionStatus, useWorkspaces, useStore, actions, startSession, open, requestSessionRename, notifyArchivedNotOpenable, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, unarchiveSession, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, useShortcuts, useWorkspaceShortcuts, requestSearch, requestAddWorkspace, closeAddWorkspace, setDirectoryBusy, dismissForkError, renderSlot, t }) {
16744
+ function WorkspaceBrowser({ wide, usePanelInfo, expandSidebar, useSessions, useSessionStatus, useWorkspaces, useStore, actions, startSession, open, requestSessionRename, notifyArchivedNotOpenable, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, unarchiveSession, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, useShortcuts, useWorkspaceShortcuts, requestSearch, requestAddWorkspace, closeAddWorkspace, setDirectoryBusy, renderSlot, t }) {
15815
16745
  const home = useHostInfo((info) => info.home);
15816
16746
  const shortcuts = useShortcuts((rows) => rows);
15817
16747
  const searchShortcut = shortcuts.find((row) => row.id === "session.search");
@@ -16240,7 +17170,7 @@ const official$2 = ((require$1) => {
16240
17170
  side: "right",
16241
17171
  onPick: (workspaceId) => {
16242
17172
  closeAddWorkspace();
16243
- startSession(workspaceId);
17173
+ startSession(workspaceId, { clearPreviousDraft: false });
16244
17174
  },
16245
17175
  onClose: () => {
16246
17176
  closeAddWorkspace();
@@ -16419,11 +17349,7 @@ const official$2 = ((require$1) => {
16419
17349
  role: "alert",
16420
17350
  children: deleteError
16421
17351
  })]
16422
- }),
16423
- shortcutState.forkError !== null && (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
16424
- text: t(shortcutState.forkError.reason === "unavailable" ? "shortcut.noCompletedTurn" : "shortcut.forkFailed"),
16425
- onDone: dismissForkError
16426
- }, shortcutState.forkError.seq)
17352
+ })
16427
17353
  ]
16428
17354
  });
16429
17355
  }
@@ -16466,6 +17392,7 @@ const official$2 = ((require$1) => {
16466
17392
  side: "bottom",
16467
17393
  align: "end",
16468
17394
  delayMs: 500,
17395
+ portal: true,
16469
17396
  children: (0, react_jsx_runtime$1.jsx)("button", {
16470
17397
  type: "button",
16471
17398
  className: Rows_module_css_default.iconButton,
@@ -16607,14 +17534,17 @@ const official$2 = ((require$1) => {
16607
17534
  /** The fork action: one `sidebar.workspaces.session.menu.item` row. */
16608
17535
  /**
16609
17536
  * Menu row (order 300): fork at the Session's last completed turn; the child
16610
- * arrives through the Host list beside its source.
16611
- * @param props - owner share, menu open state, and the fork share.
16612
- * @returns the row.
17537
+ * arrives through the Host list beside its source. Absent when the access
17538
+ * snapshot excludes `session/fork` for this Session.
17539
+ * @param props - owner share, menu open state, access Hook, and the fork share.
17540
+ * @returns the row, or nothing when the caller may not fork this Session.
16613
17541
  */
16614
- function ForkSessionMenuItem({ sessionId, useMenuOpenState, useShortcuts, forkSession, t }) {
17542
+ function ForkSessionMenuItem({ sessionId, useMenuOpenState, useShortcuts, useSessionAccess, forkSession, t }) {
16615
17543
  const [, setMenuOpen] = useMenuOpenState();
17544
+ const shortcut = useShortcuts((rows) => rows.find((row) => row.id === "session.fork"));
17545
+ if (!useSessionAccess(sessionId, "session/fork")) return null;
16616
17546
  return (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.MenuItemButton, {
16617
- shortcut: useShortcuts((rows) => rows.find((row) => row.id === "session.fork")),
17547
+ shortcut,
16618
17548
  icon: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutlineRegular, {}),
16619
17549
  onSelect: () => {
16620
17550
  setMenuOpen(false);
@@ -16671,6 +17601,7 @@ const official$2 = ((require$1) => {
16671
17601
  side: "bottom",
16672
17602
  align: "end",
16673
17603
  delayMs: 500,
17604
+ portal: true,
16674
17605
  children: (0, react_jsx_runtime$1.jsx)("button", {
16675
17606
  type: "button",
16676
17607
  className: Rows_module_css_default.iconButton,
@@ -16797,72 +17728,232 @@ const official$2 = ((require$1) => {
16797
17728
  });
16798
17729
  }
16799
17730
  /**
16800
- * The `shell.overlay` entry for Workspace and Session notices.
16801
- * One notice is visible at a time; a parent rerender does not extend its hold.
17731
+ * Dispatch the current notice without interpreting its business payload.
17732
+ * @param props - Current notice, dismissal, and the declared keyed renderer.
17733
+ * @returns The selected notice presentation, or nothing.
16802
17734
  */
17735
+ function RowActionToast({ useToast, dismissToast, renderSlot }) {
17736
+ const notice = useToast((current) => current);
17737
+ if (notice === null) return null;
17738
+ return renderSlot("workspace.toast", {
17739
+ ...notice,
17740
+ dismissToast
17741
+ }, { entryKey: notice.kind });
17742
+ }
17743
+ /** One presentation Factory and the adapters for keyed Workspace notices. */
16803
17744
  /**
16804
- * Hold for the notices that take longer to read than a one-line warning: the
16805
- * actionable archived notice (two buttons to react to) and a refused Session
16806
- * creation, which quotes the Host's reason.
17745
+ * Render one notice using the shared Factory.
17746
+ * @param props - Keyed payload, injected display mapping, locale, and Factory renderer.
17747
+ * @returns The shared Toast occurrence.
16807
17748
  */
16808
- const LONG_TOAST_HOLD_MS = 6e3;
17749
+ function ToastEntry(props) {
17750
+ const { dismissToast, display, t, renderFactorySlot, seq } = props;
17751
+ return renderFactorySlot("workspace.toast.content", {
17752
+ ...display(props, t, dismissToast),
17753
+ seq,
17754
+ onDone: dismissToast
17755
+ });
17756
+ }
16809
17757
  /**
16810
- * Render the current notice: the archived and stopped-and-archived notices
16811
- * with their undo action — plus the show-archived action while archived rows
16812
- * are hidden — on a 6 s hold, a refused Session creation with the Host's
16813
- * reason on the same hold, or a plain warning for a failed pin, an archived
16814
- * row that was clicked, or default Workspace creation.
16815
- * @param props - the notice hook, the shared viewing store, the notice dismissal, the two archived-notice actions, and the locale seat.
16816
- * @returns the notice on display, or null.
17758
+ * Keep the archive filter action reactive without subscribing unrelated notices.
17759
+ * @param props - Archive notice, display mapping, and the existing viewing store.
17760
+ * @returns The shared Toast occurrence with its current actions.
16817
17761
  */
16818
- function RowActionToast({ useToast, useStore, dismissToast, undoArchive, showArchived, t }) {
16819
- const toast = useToast((current) => current);
16820
- const archivedRowsVisible = useStore((state) => (state.archivedFilter ?? "default") !== "default");
16821
- if (toast === null) return null;
16822
- if (toast.kind === "archived" || toast.kind === "stoppedAndArchived") {
16823
- const { sessionId } = toast;
16824
- return (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
16825
- text: t(toast.kind === "archived" ? "toast.archived" : "toast.stoppedAndArchived"),
16826
- tone: "success",
16827
- holdMs: LONG_TOAST_HOLD_MS,
16828
- actions: [{
16829
- label: t("toast.archivedUndo"),
16830
- onClick: () => {
16831
- dismissToast();
16832
- undoArchive(sessionId);
16833
- }
16834
- }, ...archivedRowsVisible ? [] : [{
16835
- prefix: t("toast.archivedOr"),
16836
- label: t("toast.archivedFilter"),
16837
- onClick: () => {
16838
- dismissToast();
16839
- showArchived();
16840
- }
16841
- }]],
16842
- onDone: dismissToast
16843
- }, `toast-${String(toast.seq)}`);
16844
- }
16845
- if (toast.kind === "createFailed") return (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
16846
- text: t("toast.createFailed", { message: toast.message }),
16847
- icon: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}),
16848
- holdMs: LONG_TOAST_HOLD_MS,
17762
+ function ArchiveToastEntry(props) {
17763
+ const { dismissToast, display, filterAction, useStore, t, renderFactorySlot, seq } = props;
17764
+ const archivedVisible = useStore((state) => (state.archivedFilter ?? "default") !== "default");
17765
+ const fields = display(props, t, dismissToast);
17766
+ return renderFactorySlot("workspace.toast.content", {
17767
+ ...fields,
17768
+ actions: [...fields.actions ?? [], ...archivedVisible ? [] : [filterAction(t, dismissToast)]],
17769
+ seq,
16849
17770
  onDone: dismissToast
16850
- }, `toast-${String(toast.seq)}`);
17771
+ });
17772
+ }
17773
+ /**
17774
+ * Present plain display data with the shared primitive's timing and portal.
17775
+ * @param props - Localized display fields, display identity, and dismissal.
17776
+ * @returns One Toast, remounted only for a new display identity.
17777
+ */
17778
+ function WorkspaceToast({ seq, text, tone, holdMs, actions, onDone }) {
16851
17779
  return (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
16852
- text: plainNoticeText(toast, t),
16853
- icon: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}),
16854
- onDone: dismissToast
16855
- }, `toast-${String(toast.seq)}`);
17780
+ text,
17781
+ onDone,
17782
+ ...tone === "success" ? { tone: "success" } : {},
17783
+ ...tone === "warning" ? { icon: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}) } : {},
17784
+ ...holdMs === void 0 ? {} : { holdMs },
17785
+ ...actions === void 0 ? {} : { actions }
17786
+ }, seq);
17787
+ }
17788
+ /** Register notice presentations with their business-owned display fields and actions.
17789
+ * @param ctx - Workspace plugin context.
17790
+ * @param viewStore - Viewing store, read only by archive notices.
17791
+ * @param actions - Archive and source-opening callbacks.
17792
+ */
17793
+ function registerToasts(ctx, viewStore, actions) {
17794
+ const archiveFilterAction = (t, dismiss) => ({
17795
+ prefix: t("toast.archivedOr"),
17796
+ label: t("toast.archivedFilter"),
17797
+ onClick: () => {
17798
+ dismiss();
17799
+ actions.showArchived();
17800
+ }
17801
+ });
17802
+ ctx.slots.registerFactory({
17803
+ name: "workspace.toast.content",
17804
+ scope: "root"
17805
+ }, WorkspaceToast);
17806
+ ctx.slots.inject("workspace.toast", function* () {
17807
+ yield ctx.slots.register({
17808
+ name: "workspace.toast",
17809
+ key: "sessionIdCopied",
17810
+ locale: "workspace",
17811
+ inject: () => ({ display: (_notice, t) => ({
17812
+ text: t("toast.sessionIdCopied"),
17813
+ tone: "success"
17814
+ }) })
17815
+ }, ToastEntry);
17816
+ yield ctx.slots.register({
17817
+ name: "workspace.toast",
17818
+ key: "sessionIdCopyFailed",
17819
+ locale: "workspace",
17820
+ inject: () => ({ display: (_notice, t) => ({
17821
+ text: t("toast.sessionIdCopyFailed"),
17822
+ tone: "warning"
17823
+ }) })
17824
+ }, ToastEntry);
17825
+ yield ctx.slots.register({
17826
+ name: "workspace.toast",
17827
+ key: "pinFailed",
17828
+ locale: "workspace",
17829
+ inject: () => ({ display: (_notice, t) => ({
17830
+ text: t("toast.pinFailed"),
17831
+ tone: "warning"
17832
+ }) })
17833
+ }, ToastEntry);
17834
+ yield ctx.slots.register({
17835
+ name: "workspace.toast",
17836
+ key: "unpinFailed",
17837
+ locale: "workspace",
17838
+ inject: () => ({ display: (_notice, t) => ({
17839
+ text: t("toast.unpinFailed"),
17840
+ tone: "warning"
17841
+ }) })
17842
+ }, ToastEntry);
17843
+ yield ctx.slots.register({
17844
+ name: "workspace.toast",
17845
+ key: "archivedNotOpenable",
17846
+ locale: "workspace",
17847
+ inject: () => ({ display: (_notice, t) => ({
17848
+ text: t("toast.archivedNotOpenable"),
17849
+ tone: "warning"
17850
+ }) })
17851
+ }, ToastEntry);
17852
+ yield ctx.slots.register({
17853
+ name: "workspace.toast",
17854
+ key: "defaultWorkspaceFailed",
17855
+ locale: "workspace",
17856
+ inject: () => ({ display: (_notice, t) => ({
17857
+ text: t("defaultWorkspace.failed"),
17858
+ tone: "warning"
17859
+ }) })
17860
+ }, ToastEntry);
17861
+ yield ctx.slots.register({
17862
+ name: "workspace.toast",
17863
+ key: "shortcutForkFailed",
17864
+ locale: "workspace",
17865
+ inject: () => ({ display: (notice, t) => ({
17866
+ text: t(notice.reason === "unavailable" ? "shortcut.noCompletedTurn" : "shortcut.forkFailed"),
17867
+ tone: "plain"
17868
+ }) })
17869
+ }, ToastEntry);
17870
+ yield ctx.slots.register({
17871
+ name: "workspace.toast",
17872
+ key: "createFailed",
17873
+ locale: "workspace",
17874
+ inject: () => ({ display: (notice, t) => ({
17875
+ text: t("toast.createFailed", { message: notice.message }),
17876
+ tone: "warning",
17877
+ holdMs: 6e3
17878
+ }) })
17879
+ }, ToastEntry);
17880
+ yield ctx.slots.register({
17881
+ name: "workspace.toast",
17882
+ key: "forkRequiresOpen",
17883
+ locale: "workspace",
17884
+ inject: () => ({ display: (notice, t, dismiss) => ({
17885
+ text: t("toast.forkRequiresOpen"),
17886
+ tone: "warning",
17887
+ holdMs: 6e3,
17888
+ actions: [{
17889
+ label: t("toast.openForkSource"),
17890
+ onClick: () => {
17891
+ dismiss();
17892
+ actions.openForkSource(notice.sessionId);
17893
+ }
17894
+ }]
17895
+ }) })
17896
+ }, ToastEntry);
17897
+ yield ctx.slots.register({
17898
+ name: "workspace.toast",
17899
+ key: "archived",
17900
+ locale: "workspace",
17901
+ store: viewStore,
17902
+ inject: () => ({
17903
+ display: (notice, t, dismiss) => ({
17904
+ text: t("toast.archived"),
17905
+ tone: "success",
17906
+ holdMs: 6e3,
17907
+ actions: [{
17908
+ label: t("toast.archivedUndo"),
17909
+ onClick: () => {
17910
+ dismiss();
17911
+ actions.undoArchive(notice.sessionId);
17912
+ }
17913
+ }]
17914
+ }),
17915
+ filterAction: archiveFilterAction
17916
+ })
17917
+ }, ArchiveToastEntry);
17918
+ yield ctx.slots.register({
17919
+ name: "workspace.toast",
17920
+ key: "stoppedAndArchived",
17921
+ locale: "workspace",
17922
+ store: viewStore,
17923
+ inject: () => ({
17924
+ display: (notice, t, dismiss) => ({
17925
+ text: t("toast.stoppedAndArchived"),
17926
+ tone: "success",
17927
+ holdMs: 6e3,
17928
+ actions: [{
17929
+ label: t("toast.archivedUndo"),
17930
+ onClick: () => {
17931
+ dismiss();
17932
+ actions.undoArchive(notice.sessionId);
17933
+ }
17934
+ }]
17935
+ }),
17936
+ filterAction: archiveFilterAction
17937
+ })
17938
+ }, ArchiveToastEntry);
17939
+ });
16856
17940
  }
16857
- /** The copy of one plain warning, keyed by the notice kind the union closes over. */
16858
- function plainNoticeText(toast, t) {
16859
- switch (toast.kind) {
16860
- case "pinFailed": return t("toast.pinFailed");
16861
- case "unpinFailed": return t("toast.unpinFailed");
16862
- case "defaultWorkspaceFailed": return t("defaultWorkspace.failed");
16863
- case "archivedNotOpenable": return t("toast.archivedNotOpenable");
16864
- default: return assertNever$1(toast);
16865
- }
17941
+ /** Copy the row's Session ID without opening its history. */
17942
+ /**
17943
+ * Copy the complete ID after dismissing the row menu.
17944
+ * @param props - Row identity, menu dismissal, clipboard action, and locale.
17945
+ * @returns The final built-in menu item.
17946
+ */
17947
+ function SessionIdMenuItem({ sessionId, useMenuOpenState, copySessionId, t }) {
17948
+ const [, setMenuOpen] = useMenuOpenState();
17949
+ return (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.MenuItemButton, {
17950
+ icon: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular, {}),
17951
+ onSelect: () => {
17952
+ setMenuOpen(false);
17953
+ copySessionId(sessionId);
17954
+ },
17955
+ children: t("menu.sessionId")
17956
+ });
16866
17957
  }
16867
17958
  /**
16868
17959
  * `workspace` namespace dictionaries: the browsing region (section header,
@@ -16880,6 +17971,8 @@ const official$2 = ((require$1) => {
16880
17971
  "dshGitWorktree.state.finalized": "已完成",
16881
17972
  "dshGitWorktree.state.discarded": "已放弃",
16882
17973
  "defaultWorkspace.failed": "无法创建默认工作区,请通过“选择工作区”选择文件夹",
17974
+ "draft.workspaceRequired": "请先选择工作区",
17975
+ "draft.initializationFailed": "暂时无法填入草稿,请稍后重试",
16883
17976
  "group.ungrouped": "未分组",
16884
17977
  "session.new": "新会话",
16885
17978
  "session.untitled": "未命名",
@@ -16934,6 +18027,9 @@ const official$2 = ((require$1) => {
16934
18027
  "menu.unarchiveSession": "取消归档",
16935
18028
  "menu.pinSession": "置顶会话",
16936
18029
  "menu.unpinSession": "取消置顶",
18030
+ "menu.sessionId": "复制 Session ID",
18031
+ "toast.sessionIdCopied": "Session ID 已复制",
18032
+ "toast.sessionIdCopyFailed": "复制失败,请重试",
16937
18033
  "row.archived": "已归档",
16938
18034
  "row.pinned": "已置顶",
16939
18035
  "toast.archivedNotOpenable": "已归档对话暂时无法查看,请取消归档后查看",
@@ -16960,6 +18056,8 @@ const official$2 = ((require$1) => {
16960
18056
  "toast.pinFailed": "置顶失败,请稍后重试",
16961
18057
  "toast.unpinFailed": "取消置顶失败,请稍后重试",
16962
18058
  "toast.createFailed": "新建会话失败:{message}",
18059
+ "toast.forkRequiresOpen": "请先打开原会话完成迁移,再创建分支",
18060
+ "toast.openForkSource": "打开原会话",
16963
18061
  "sessions.count.one": "{n} 个会话",
16964
18062
  "sessions.count.other": "{n} 个会话",
16965
18063
  "actions.workspace.aria": "工作区“{name}”的操作",
@@ -17003,6 +18101,8 @@ const official$2 = ((require$1) => {
17003
18101
  "dshGitWorktree.state.finalized": "Done",
17004
18102
  "dshGitWorktree.state.discarded": "Discarded",
17005
18103
  "defaultWorkspace.failed": "Unable to create default workspace. Use Choose workspace to select a folder.",
18104
+ "draft.workspaceRequired": "Choose a workspace first.",
18105
+ "draft.initializationFailed": "Could not fill the draft. Please try again shortly.",
17006
18106
  "group.ungrouped": "Ungrouped",
17007
18107
  "session.new": "New Session",
17008
18108
  "session.untitled": "Untitled",
@@ -17057,6 +18157,9 @@ const official$2 = ((require$1) => {
17057
18157
  "menu.unarchiveSession": "Unarchive session",
17058
18158
  "menu.pinSession": "Pin session",
17059
18159
  "menu.unpinSession": "Unpin session",
18160
+ "menu.sessionId": "Copy Session ID",
18161
+ "toast.sessionIdCopied": "Session ID copied",
18162
+ "toast.sessionIdCopyFailed": "Copy failed. Try again.",
17060
18163
  "row.archived": "Archived",
17061
18164
  "row.pinned": "Pinned",
17062
18165
  "toast.archivedNotOpenable": "Archived sessions cannot be opened. Unarchive it to view.",
@@ -17083,6 +18186,8 @@ const official$2 = ((require$1) => {
17083
18186
  "toast.pinFailed": "Pin failed. Try again later.",
17084
18187
  "toast.unpinFailed": "Unpin failed. Try again later.",
17085
18188
  "toast.createFailed": "New session failed: {message}",
18189
+ "toast.forkRequiresOpen": "Open the original session to complete migration before creating a branch.",
18190
+ "toast.openForkSource": "Open original session",
17086
18191
  "sessions.count.one": "{n} session",
17087
18192
  "sessions.count.other": "{n} sessions",
17088
18193
  "actions.workspace.aria": "Workspace actions for {name}",
@@ -17133,7 +18238,8 @@ const official$2 = ((require$1) => {
17133
18238
  "remote",
17134
18239
  "remote.directoryPicker",
17135
18240
  "layout",
17136
- "shortcuts"
18241
+ "shortcuts",
18242
+ "remoteAccess"
17137
18243
  ];
17138
18244
  /**
17139
18245
  * Register the browser and picker once their slot declarations are on the
@@ -17159,7 +18265,10 @@ const official$2 = ((require$1) => {
17159
18265
  });
17160
18266
  };
17161
18267
  const uiWorkspace = new UiWorkspaceService(ctx, ctx.remote.directoryPicker, workspaces, sessions, viewInstance.actions, notify);
17162
- ctx.slots.provideRoot({ hooks: { workspaces: workspaces.list } });
18268
+ ctx.slots.provideRoot({
18269
+ hooks: { workspaces: workspaces.list },
18270
+ keyedHooks: { workspaceAccess: (workspaceId, action) => action === void 0 ? void 0 : ctx.remoteAccess.source("workspace", workspaceId, action) }
18271
+ });
17163
18272
  ctx.effect(() => ctx.locale.register(NS, {
17164
18273
  zh,
17165
18274
  en
@@ -17237,7 +18346,12 @@ const official$2 = ((require$1) => {
17237
18346
  },
17238
18347
  unarchiveSession
17239
18348
  });
17240
- installWorkspaceShortcuts(ctx, uiWorkspace, shortcutControls, archiveInjected().archiveSession);
18349
+ installWorkspaceShortcuts(ctx, uiWorkspace, shortcutControls, archiveInjected().archiveSession, (reason) => {
18350
+ notify({
18351
+ kind: "shortcutForkFailed",
18352
+ reason
18353
+ });
18354
+ });
17241
18355
  const archiveConfirmInjected = () => ({
17242
18356
  hooks: { archiveRequest },
17243
18357
  settleSessionArchive: () => {
@@ -17258,7 +18372,15 @@ const official$2 = ((require$1) => {
17258
18372
  parent_session_id: sessionId,
17259
18373
  click_position: "sidebar"
17260
18374
  });
17261
- }).catch(() => {});
18375
+ }, { allowMigration: false }).catch((error) => {
18376
+ if (error instanceof Error && error.name === "SessionForkError" && error.rpcError.code === "session/migration-required") notify({
18377
+ kind: "forkRequiresOpen",
18378
+ sessionId
18379
+ });
18380
+ });
18381
+ } });
18382
+ const sessionIdInjected = () => ({ copySessionId: async (sessionId) => {
18383
+ notify({ kind: await (0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(sessionId) ? "sessionIdCopied" : "sessionIdCopyFailed" });
17262
18384
  } });
17263
18385
  const renameInjected = () => ({ requestSessionRename });
17264
18386
  const renameDialogInjected = () => ({
@@ -17266,19 +18388,28 @@ const official$2 = ((require$1) => {
17266
18388
  settleSessionRename: shortcutControls.closeRename,
17267
18389
  renameSession
17268
18390
  });
18391
+ registerToasts(ctx, viewStore, {
18392
+ undoArchive: unarchiveSession,
18393
+ showArchived: () => {
18394
+ viewInstance.actions.setArchivedFilter("show");
18395
+ },
18396
+ openForkSource: (sessionId) => {
18397
+ if (workspaces.list.getSnapshot().archivedSessionIds.includes(sessionId)) {
18398
+ notify({ kind: "archivedNotOpenable" });
18399
+ return;
18400
+ }
18401
+ openSession(sessionId);
18402
+ }
18403
+ });
17269
18404
  const rowToastInjected = () => ({
17270
18405
  hooks: { toast: rowToast },
17271
18406
  dismissToast: () => {
17272
18407
  rowToast.set(null);
17273
- },
17274
- undoArchive: unarchiveSession,
17275
- showArchived: () => {
17276
- viewInstance.actions.setArchivedFilter("show");
17277
18408
  }
17278
18409
  });
17279
18410
  const browserInjected = () => ({
17280
- startSession: (workspaceId) => {
17281
- uiWorkspace.startSession(workspaceId);
18411
+ startSession: (workspaceId, options) => {
18412
+ uiWorkspace.startSession(workspaceId, options);
17282
18413
  },
17283
18414
  open: openSession,
17284
18415
  searchSessions,
@@ -17304,7 +18435,6 @@ const official$2 = ((require$1) => {
17304
18435
  requestAddWorkspace: shortcutControls.add,
17305
18436
  closeAddWorkspace: shortcutControls.closeAdd,
17306
18437
  setDirectoryBusy: shortcutControls.directoryBusy,
17307
- dismissForkError: shortcutControls.dismissForkError,
17308
18438
  hooks: {
17309
18439
  directoryFlow: browserFlowSource,
17310
18440
  hostInfo,
@@ -17377,6 +18507,13 @@ const official$2 = ((require$1) => {
17377
18507
  locale: NS,
17378
18508
  inject: archiveInjected
17379
18509
  }, ArchiveSessionMenuItem);
18510
+ yield ctx.slots.register({
18511
+ name: "sidebar.workspaces.session.menu.item",
18512
+ id: "session-id",
18513
+ order: 450,
18514
+ locale: NS,
18515
+ inject: sessionIdInjected
18516
+ }, SessionIdMenuItem);
17380
18517
  });
17381
18518
  ctx.slots.inject("sidebar.workspaces.session.row.action", function* () {
17382
18519
  yield ctx.slots.register({
@@ -17410,9 +18547,11 @@ const official$2 = ((require$1) => {
17410
18547
  yield ctx.slots.register({
17411
18548
  name: "shell.overlay",
17412
18549
  id: "workspace.row-toast",
17413
- locale: NS,
17414
- store: viewStore,
17415
- inject: rowToastInjected
18550
+ inject: rowToastInjected,
18551
+ children: { "workspace.toast": {
18552
+ kind: "keyed",
18553
+ scope: "root"
18554
+ } }
17416
18555
  }, RowActionToast);
17417
18556
  });
17418
18557
  ctx.slots.inject("conversation.hero.workspace", () => ctx.slots.register({
@@ -17573,6 +18712,12 @@ function projectManagedWorkspaceSidebar(input, t = defaultClientTranslator) {
17573
18712
  //#endregion
17574
18713
  //#region src/client/workspace-sidebar/index.tsx
17575
18714
  const EMPTY_TOPOLOGY = { projects: [] };
18715
+ const OWNER_SAFE_SESSION_ACTIONS = new Set([
18716
+ "pin",
18717
+ "rename",
18718
+ "archive",
18719
+ "session-id"
18720
+ ]);
17576
18721
  /**
17577
18722
  * Preserve the complete official Workspace Browser and change only its data
17578
18723
  * projection plus mutations that are unsafe for one-to-one Managed owners.
@@ -17732,7 +18877,7 @@ function officialContextProxy(ctx, adapter) {
17732
18877
  };
17733
18878
  const proxySlots = new Proxy(ctx.slots, { get(target, key, receiver) {
17734
18879
  if (key === "register") return (descriptor$1, component) => {
17735
- if ((descriptor$1.name === "sidebar.workspaces.session.menu.item" || descriptor$1.name === "sidebar.workspaces.session.row.action") && descriptor$1.id !== "pin") {
18880
+ if ((descriptor$1.name === "sidebar.workspaces.session.menu.item" || descriptor$1.name === "sidebar.workspaces.session.row.action") && !OWNER_SAFE_SESSION_ACTIONS.has(descriptor$1.id)) {
17736
18881
  const Action = component;
17737
18882
  const GuardedAction = (props) => typeof props.sessionId === "string" && !guard.blockSession(props.sessionId) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Action, { ...props }) : null;
17738
18883
  return target.register(descriptor$1, GuardedAction);
@@ -18541,6 +19686,7 @@ const official$1 = ((require$1) => {
18541
19686
  */
18542
19687
  constructor(ctx, directoryPicker, workspaces, sessions, view, notify) {
18543
19688
  super(ctx, "uiWorkspace");
19689
+ this.managedWorktreeGuard = ctx.get("__dshGitWorktreeManagedGuard");
18544
19690
  this.directoryPicker = directoryPicker;
18545
19691
  this.workspaces = workspaces;
18546
19692
  this.sessions = sessions;
@@ -18608,7 +19754,7 @@ const official$1 = ((require$1) => {
18608
19754
  this.replaceMain(sessionId, navigation, "reveal", beforeOpen);
18609
19755
  }
18610
19756
  async forkSession(sessionId) {
18611
- if (this.ctx.get("__dshGitWorktreeManagedGuard").blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
19757
+ if (this.managedWorktreeGuard.blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
18612
19758
  await this.sessions.fork({
18613
19759
  sessionId,
18614
19760
  increaseTitle: true
@@ -18621,7 +19767,7 @@ const official$1 = ((require$1) => {
18621
19767
  const currentWorkspaceId = current === void 0 ? void 0 : workspace.items.find((item) => item.sessionIds.includes(current))?.workspaceId;
18622
19768
  const recent = workspace.phase === "ready" && sessions.phase === "ready" ? recentWorkspace(workspace.items, sessions.byId) : void 0;
18623
19769
  const target = workspaceId ?? currentWorkspaceId ?? recent;
18624
- if (target !== void 0 && this.ctx.get("__dshGitWorktreeManagedGuard").blockWorkspace(target)) return;
19770
+ if (target !== void 0 && this.managedWorktreeGuard.blockWorkspace(target)) return;
18625
19771
  if (target === void 0) {
18626
19772
  this.clearMain();
18627
19773
  return;
@@ -18631,7 +19777,6 @@ const official$1 = ((require$1) => {
18631
19777
  });
18632
19778
  }
18633
19779
  async archiveSession(sessionId, options = {}) {
18634
- if (this.ctx.get("__dshGitWorktreeManagedGuard").blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
18635
19780
  await this.workspaces.archiveSession(sessionId, options);
18636
19781
  if (this.mainReference?.sessionId === sessionId) this.clearMain();
18637
19782
  }
@@ -18828,10 +19973,10 @@ const official$1 = ((require$1) => {
18828
19973
  return title === "default-workspace" ? localizedDefault : title;
18829
19974
  }
18830
19975
  const css$3 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{border-radius:var(--dsw-radius-md);padding:0 8px;cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);align-items:center;gap:6px;padding-inline-start:calc(8px + var(--dsh-workspace-indent,0px));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;border-radius:var(--dsw-radius-lg);cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--dsw-alias-label-primary);background:0 0;border:none;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_searchResultWorkspace:only-child{max-width:100%}.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{gap:0;height:32px}.YDXeBa_sessionRow .YDXeBa_title{margin:0 6px 0 4px}.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);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-button-elevated-fill);min-width:0;color:inherit;outline:none;padding:0 2px;font-size:14px;line-height:20px}.YDXeBa_sessionRow .YDXeBa_title{flex:1}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled]{mask-image:linear-gradient(90deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-clipped]{mask-image:linear-gradient(270deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled][data-clipped]{mask-image:linear-gradient(90deg,#0000,#000 12px calc(100% - 12px),#0000)}.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:10px;line-height:16px}.YDXeBa_pinIndicator{width:16px;height:20px;color:var(--dsw-alias-label-caption);flex:none;justify-content:center;align-items:center;margin-left:6px;display:inline-flex}.YDXeBa_sessionRow.YDXeBa_archived .YDXeBa_title,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultTitle,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultWorkspace,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultSnippet{color:var(--dsw-alias-label-caption)}.YDXeBa_dot{flex:none}.YDXeBa_rowActions{flex:none;align-items:center;gap:10px;display:none}.YDXeBa_projectRow:hover .YDXeBa_rowActions,.YDXeBa_sessionRow:hover .YDXeBa_rowActions,.YDXeBa_searchResultRow:hover .YDXeBa_rowActions,.YDXeBa_projectRow.YDXeBa_menuOpen .YDXeBa_rowActions,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_rowActions{display:inline-flex}.YDXeBa_searchResultHeading .YDXeBa_rowActions{margin-left:auto}.YDXeBa_sessionRow:hover .YDXeBa_time,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_time,.YDXeBa_sessionRow:hover .YDXeBa_pinIndicator,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_pinIndicator{display:none}@media (hover:hover){.YDXeBa_sessionRow:hover .YDXeBa_title,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_title{text-overflow:clip}}.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_hoverArchived svg{flex-shrink:0;margin:0 -4px}.YDXeBa_iconButton{border-radius:var(--dsw-radius-xs);cursor:pointer;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;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_arrow{transition:none;animation:none}}";
18831
- const tagId$3 = "@deepseek-ai/dsh-client-ui-workspace/Rows.module.css";
19976
+ const tagId$3 = "dsh-git-worktree/workspace-0.1.7-rc.2/Rows.module.css";
18832
19977
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
18833
19978
  const tag = document.createElement("style");
18834
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
19979
+ tag.dataset.plugin = "dsh-git-worktree";
18835
19980
  tag.dataset.pluginCss = tagId$3;
18836
19981
  tag.textContent = css$3;
18837
19982
  document.head.appendChild(tag);
@@ -19402,13 +20547,13 @@ const official$1 = ((require$1) => {
19402
20547
  (0, react_jsx_runtime$1.jsx)("span", {
19403
20548
  ref: titleRef,
19404
20549
  className: Rows_module_css_default.title,
19405
- onDoubleClick: row.blank || protectedManagedSession ? void 0 : (e) => {
20550
+ onDoubleClick: row.blank ? void 0 : (e) => {
19406
20551
  e.stopPropagation();
19407
20552
  onRenameRequest(node.id, row.title);
19408
20553
  },
19409
20554
  children: title
19410
20555
  }),
19411
- protectedManagedSession && (0, react_jsx_runtime$1.jsx)("span", {
20556
+ protectedManagedSession && node.__dshGitWorktree.state !== "working" && (0, react_jsx_runtime$1.jsx)("span", {
19412
20557
  className: "dsh-git-worktree-sidebar-badge",
19413
20558
  "data-worktree-state": node.__dshGitWorktree.state,
19414
20559
  children: node.__dshGitWorktree.label
@@ -19465,10 +20610,10 @@ const official$1 = ((require$1) => {
19465
20610
  });
19466
20611
  }
19467
20612
  const css$2 = ".Qg_5Eq_exits{contain:strict;pointer-events:none;position:absolute;inset:0;overflow:clip}";
19468
- const tagId$2 = "@deepseek-ai/dsh-client-ui-workspace/AnimatedRows.module.css";
20613
+ const tagId$2 = "dsh-git-worktree/workspace-0.1.7-rc.2/AnimatedRows.module.css";
19469
20614
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
19470
20615
  const tag = document.createElement("style");
19471
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
20616
+ tag.dataset.plugin = "dsh-git-worktree";
19472
20617
  tag.dataset.pluginCss = tagId$2;
19473
20618
  tag.textContent = css$2;
19474
20619
  document.head.appendChild(tag);
@@ -19637,10 +20782,10 @@ const official$1 = ((require$1) => {
19637
20782
  }
19638
20783
  };
19639
20784
  const css$1 = "._G5b-a_modalAction{min-width:72px}._G5b-a_modalError,._G5b-a_menuStatus{margin-top:8px;font-size:12px;line-height:18px}._G5b-a_modalError{color:var(--dsw-alias-state-error-primary)}._G5b-a_menuStatus{color:var(--dsw-alias-label-secondary)}";
19640
- const tagId$1 = "@deepseek-ai/dsh-client-ui-workspace/WorkspacePicker.module.css";
20785
+ const tagId$1 = "dsh-git-worktree/workspace-0.1.7-rc.2/WorkspacePicker.module.css";
19641
20786
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
19642
20787
  const tag = document.createElement("style");
19643
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
20788
+ tag.dataset.plugin = "dsh-git-worktree";
19644
20789
  tag.dataset.pluginCss = tagId$1;
19645
20790
  tag.textContent = css$1;
19646
20791
  document.head.appendChild(tag);
@@ -19806,10 +20951,10 @@ const official$1 = ((require$1) => {
19806
20951
  });
19807
20952
  }
19808
20953
  const css = ".bhn1Oq_root{--dsh-session-list-edge-inset:var(--dsh-sidebar-inline-padding);--dsh-session-list-scrollbar-width:5px;--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{border-radius:var(--dsw-radius-sm);cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.bhn1Oq_iconButton:focus-visible,.bhn1Oq_searchButton:focus-visible,.bhn1Oq_clearButton:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}.bhn1Oq_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.bhn1Oq_viewOptionsMenu{min-width:200px}.bhn1Oq_sectionHeader{box-sizing:border-box;border-radius:var(--dsw-radius-md);height:36px;color:var(--dsw-alias-label-tertiary);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;border-radius:var(--dsw-radius-sm);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;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);border-radius:var(--dsw-radius-md);width:calc(100% + 4px);height:30px;color:var(--dsw-alias-label-caption);background:0 0;margin-inline:-2px;padding:0 4px 0 0}.bhn1Oq_searchButton{border-radius:var(--dsw-radius-sm);cursor:pointer;width:28px;height:28px;color:inherit;background:0 0;border:none;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{border-radius:var(--dsw-radius-sm);cursor:pointer;width:24px;height:24px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;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{border-radius:var(--dsw-radius-md);width:36px;height:36px;color:var(--dsw-alias-label-primary)}.bhn1Oq_rail .bhn1Oq_search{border-radius:var(--dsw-radius-md);background:0 0;border-color:#0000;gap:0;width:36px;height:36px;margin:0 0 12px;padding:0}.bhn1Oq_rail .bhn1Oq_searchButton{border-radius:var(--dsw-radius-md);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}[data-platform=darwin] .bhn1Oq_fade{display:none}.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{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:12px;line-height:18px}.bhn1Oq_skeletonRow{box-sizing:border-box;align-items:flex-start;gap:8px;min-height:48px;padding:6px 8px 7px;display:flex}.bhn1Oq_skeletonDot{corner-shape:round;border-radius:50%;flex:none;width:16px;height:16px}.bhn1Oq_skeletonBars{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.bhn1Oq_skeletonDot,.bhn1Oq_skeletonBar{background:var(--dsw-alias-bg-skeleton);animation:2s cubic-bezier(.36,0,.64,1) infinite bhn1Oq_search-skeleton}.bhn1Oq_skeletonBar{border-radius:var(--dsw-radius-xs);width:65%;height:16px}.bhn1Oq_skeletonBarWide{width:90%;height:13px}@keyframes bhn1Oq_search-skeleton{0%{opacity:1}40%{opacity:.6}80%,to{opacity:1}}.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{border-radius:var(--dsw-radius-sm);width:100%;height:28px;padding:0 12px 0 calc(28px + var(--dsh-workspace-indent,0px));cursor:pointer;text-align:left;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;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_emptyState{color:var(--dsw-alias-label-tertiary);flex-direction:column;align-items:center;gap:8px;margin-top:80px;padding:0 12px;font-size:13px;line-height:20px;display:flex}.bhn1Oq_emptyState>svg{color:var(--dsw-alias-label-caption);margin-bottom:4px}.bhn1Oq_emptyAction{cursor:pointer;color:var(--dsw-alias-link);background:0 0;border:none;padding:0;font-size:13px;line-height:20px}.bhn1Oq_renameInput{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);width:100%;height:44px;color:var(--dsw-alias-label-primary);background:0 0;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}.bhn1Oq_archiveActivity{color:var(--dsw-alias-label-primary);margin:0 0 8px;padding-left:18px;font-size:13px;line-height:20px}.bhn1Oq_archiveActivity li{overflow-wrap:anywhere}@media (prefers-reduced-motion:reduce){.bhn1Oq_wide,.bhn1Oq_skeletonDot,.bhn1Oq_skeletonBar{animation:none}.bhn1Oq_search,.bhn1Oq_sectionLabel,.bhn1Oq_searchSlot,.bhn1Oq_searchInput,.bhn1Oq_headerActions{transition:none}}";
19809
- const tagId = "@deepseek-ai/dsh-client-ui-workspace/WorkspaceBrowser.module.css";
20954
+ const tagId = "dsh-git-worktree/workspace-0.1.7-rc.2/WorkspaceBrowser.module.css";
19810
20955
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
19811
20956
  const tag = document.createElement("style");
19812
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
20957
+ tag.dataset.plugin = "dsh-git-worktree";
19813
20958
  tag.dataset.pluginCss = tagId;
19814
20959
  tag.textContent = css;
19815
20960
  document.head.appendChild(tag);
@@ -21925,7 +23070,6 @@ const official$1 = ((require$1) => {
21925
23070
  });
21926
23071
  };
21927
23072
  const renameSession = async (sessionId, title) => {
21928
- if (ctx.get("__dshGitWorktreeManagedGuard").blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
21929
23073
  const result = await sessions.using(sessionId, { source: "workspaceOperation" }, (reference) => reference.binding.session.rename(title));
21930
23074
  if (!result.ok) throw new Error(result.error.message);
21931
23075
  };
@@ -22218,6 +23362,7 @@ const official = ((require$1) => {
22218
23362
  */
22219
23363
  constructor(ctx, directoryPicker, workspaces, sessions) {
22220
23364
  super(ctx, "uiWorkspace");
23365
+ this.managedWorktreeGuard = ctx.get("__dshGitWorktreeManagedGuard");
22221
23366
  this.directoryPicker = directoryPicker;
22222
23367
  this.workspaces = workspaces;
22223
23368
  this.sessions = sessions;
@@ -22259,7 +23404,7 @@ const official = ((require$1) => {
22259
23404
  this.replaceMain(sessionId, navigation, beforeOpen);
22260
23405
  }
22261
23406
  async forkSession(sessionId) {
22262
- if (this.ctx.get("__dshGitWorktreeManagedGuard").blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
23407
+ if (this.managedWorktreeGuard.blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
22263
23408
  const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]);
22264
23409
  const childId = await this.sessions.fork({
22265
23410
  sessionId,
@@ -22274,7 +23419,7 @@ const official = ((require$1) => {
22274
23419
  const currentWorkspaceId = current === void 0 ? void 0 : workspace.items.find((item) => item.sessionIds.includes(current))?.workspaceId;
22275
23420
  const recent = workspace.phase === "ready" && sessions.phase === "ready" ? recentWorkspace(workspace.items, sessions.byId) : void 0;
22276
23421
  const target = workspaceId ?? currentWorkspaceId ?? recent;
22277
- if (target !== void 0 && this.ctx.get("__dshGitWorktreeManagedGuard").blockWorkspace(target)) return;
23422
+ if (target !== void 0 && this.managedWorktreeGuard.blockWorkspace(target)) return;
22278
23423
  if (target === void 0) {
22279
23424
  this.clearMain();
22280
23425
  return;
@@ -22284,7 +23429,6 @@ const official = ((require$1) => {
22284
23429
  });
22285
23430
  }
22286
23431
  async archiveSession(sessionId) {
22287
- if (this.ctx.get("__dshGitWorktreeManagedGuard").blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
22288
23432
  await this.workspaces.archiveSession(sessionId);
22289
23433
  if (this.mainReference?.sessionId === sessionId) this.clearMain();
22290
23434
  }
@@ -22867,10 +24011,10 @@ const official = ((require$1) => {
22867
24011
  return owner;
22868
24012
  }
22869
24013
  const css$2 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{padding:0 8px;cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;gap:6px;padding-inline-start:calc(8px + var(--dsh-workspace-indent,0px));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{scroll-behavior:smooth;flex:1}@media (hover:hover){.YDXeBa_sessionRow:hover .YDXeBa_title{text-overflow:clip}}.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}.YDXeBa_sessionRow .YDXeBa_title{scroll-behavior:auto}}";
22870
- const tagId$2 = "@deepseek-ai/dsh-client-ui-workspace/Rows.module.css";
24014
+ const tagId$2 = "dsh-git-worktree/workspace-0.1.6-alpha.2/Rows.module.css";
22871
24015
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
22872
24016
  const tag = document.createElement("style");
22873
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
24017
+ tag.dataset.plugin = "dsh-git-worktree";
22874
24018
  tag.dataset.pluginCss = tagId$2;
22875
24019
  tag.textContent = css$2;
22876
24020
  document.head.appendChild(tag);
@@ -23303,6 +24447,7 @@ const official = ((require$1) => {
23303
24447
  icon: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, { size: 16 })
23304
24448
  }
23305
24449
  ];
24450
+ const visibleSessionMenuItems = protectedManagedSession ? sessionMenuItems.filter((item) => item.id !== "fork") : sessionMenuItems;
23306
24451
  return (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.HoverCard, {
23307
24452
  anchor: (0, react_jsx_runtime$1.jsxs)("div", {
23308
24453
  ref: rowRef,
@@ -23355,7 +24500,7 @@ const official = ((require$1) => {
23355
24500
  className: Rows_module_css_default.title,
23356
24501
  children: title
23357
24502
  }),
23358
- protectedManagedSession && (0, react_jsx_runtime$1.jsx)("span", {
24503
+ protectedManagedSession && node.__dshGitWorktree.state !== "working" && (0, react_jsx_runtime$1.jsx)("span", {
23359
24504
  className: "dsh-git-worktree-sidebar-badge",
23360
24505
  "data-worktree-state": node.__dshGitWorktree.state,
23361
24506
  children: node.__dshGitWorktree.label
@@ -23365,14 +24510,14 @@ const official = ((require$1) => {
23365
24510
  className: Rows_module_css_default.time,
23366
24511
  children: timeLabel(row.updatedAt, now, t)
23367
24512
  }),
23368
- !row.blank && !protectedManagedSession && (0, react_jsx_runtime$1.jsx)("span", {
24513
+ !row.blank && (0, react_jsx_runtime$1.jsx)("span", {
23369
24514
  className: Rows_module_css_default.rowActions,
23370
24515
  children: (0, react_jsx_runtime$1.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
23371
24516
  open: menuOpen,
23372
24517
  onClose: () => {
23373
24518
  setMenuOpen(false);
23374
24519
  },
23375
- items: sessionMenuItems,
24520
+ items: visibleSessionMenuItems,
23376
24521
  onSelect: (id) => {
23377
24522
  setMenuOpen(false);
23378
24523
  if (id === "rename") onRename(node.id, row.title);
@@ -23407,10 +24552,10 @@ const official = ((require$1) => {
23407
24552
  });
23408
24553
  }
23409
24554
  const css$1 = "._G5b-a_modalAction{min-width:72px}._G5b-a_modalError,._G5b-a_menuStatus{margin-top:8px;font-size:12px;line-height:18px}._G5b-a_modalError{color:var(--dsw-alias-state-error-primary)}._G5b-a_menuStatus{color:var(--dsw-alias-label-secondary)}";
23410
- const tagId$1 = "@deepseek-ai/dsh-client-ui-workspace/WorkspacePicker.module.css";
24555
+ const tagId$1 = "dsh-git-worktree/workspace-0.1.6-alpha.2/WorkspacePicker.module.css";
23411
24556
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
23412
24557
  const tag = document.createElement("style");
23413
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
24558
+ tag.dataset.plugin = "dsh-git-worktree";
23414
24559
  tag.dataset.pluginCss = tagId$1;
23415
24560
  tag.textContent = css$1;
23416
24561
  document.head.appendChild(tag);
@@ -23573,10 +24718,10 @@ const official = ((require$1) => {
23573
24718
  });
23574
24719
  }
23575
24720
  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);border-radius:12px}.bhn1Oq_rail .bhn1Oq_search{background:0 0;border-color:#0000;border-radius:12px;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);border-radius:12px}.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}[data-platform=darwin] .bhn1Oq_fade{display:none}.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{width:100%;height:28px;padding:0 12px 0 calc(28px + var(--dsh-workspace-indent,0px));cursor:pointer;text-align:left;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:8px;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}}";
23576
- const tagId = "@deepseek-ai/dsh-client-ui-workspace/WorkspaceBrowser.module.css";
24721
+ const tagId = "dsh-git-worktree/workspace-0.1.6-alpha.2/WorkspaceBrowser.module.css";
23577
24722
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
23578
24723
  const tag = document.createElement("style");
23579
- tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-workspace";
24724
+ tag.dataset.plugin = "dsh-git-worktree";
23580
24725
  tag.dataset.pluginCss = tagId;
23581
24726
  tag.textContent = css;
23582
24727
  document.head.appendChild(tag);
@@ -25088,7 +26233,6 @@ const official = ((require$1) => {
25088
26233
  searchSessions,
25089
26234
  searchResultLimit: sessions.searchResultLimit,
25090
26235
  renameSession: async (sessionId, title) => {
25091
- if (ctx.get("__dshGitWorktreeManagedGuard").blockSession(sessionId)) throw new Error("managed Session must be changed through its Worktree owner");
25092
26236
  const result = await sessions.using(sessionId, { source: "workspaceOperation" }, (reference) => reference.binding.session.rename(title));
25093
26237
  if (!result.ok) throw new Error(result.error.message);
25094
26238
  },