dsh-plugin-t-expert 0.3.6 → 0.3.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -19978,7 +19978,8 @@ var scheduleSnapshotSchema = external_exports.object({
19978
19978
  /** 正在执行中的事项 id(面板据此显示「执行中…」)。 */
19979
19979
  running: external_exports.array(external_exports.string()),
19980
19980
  capabilities: external_exports.object({ agents: external_exports.boolean(), presets: external_exports.boolean() }),
19981
- workspaces: external_exports.array(external_exports.object({ id: external_exports.string(), title: external_exports.string() }))
19981
+ /** 可选工作区(下拉选项);path 是目录,面板显示给用户看落地位置。 */
19982
+ workspaces: external_exports.array(external_exports.object({ id: external_exports.string(), title: external_exports.string(), path: external_exports.string().optional() }))
19982
19983
  });
19983
19984
  var scheduleInputSchema = external_exports.object({
19984
19985
  title: external_exports.string().min(1).max(200),
@@ -19991,10 +19992,13 @@ var scheduleInputSchema = external_exports.object({
19991
19992
  var schedulePatchSchema = scheduleInputSchema.partial();
19992
19993
  var schedulePreviewSchema = external_exports.object({ fires: external_exports.array(external_exports.string()) });
19993
19994
  var scheduleArmedSchema = external_exports.object({ armed: external_exports.boolean() });
19995
+ var scheduleWorkspaceSchema = external_exports.object({
19996
+ workspace: external_exports.object({ id: external_exports.string(), title: external_exports.string(), path: external_exports.string() })
19997
+ });
19994
19998
 
19995
19999
  // src/client.jsx
19996
20000
  var NS = "t-team";
19997
- var CLIENT_BUILD_VERSION = "0.3.6";
20001
+ var CLIENT_BUILD_VERSION = "0.3.24";
19998
20002
  var uiPrefs = { showTaskBadge: true, showScheduleButton: true };
19999
20003
  var uiPrefsListeners = /* @__PURE__ */ new Set();
20000
20004
  function setUiPrefs(next) {
@@ -20238,6 +20242,11 @@ var zh = {
20238
20242
  "sched.workspace": "\u5DE5\u4F5C\u533A",
20239
20243
  "sched.workspaceNone": "\u4E0D\u7ED1\u5B9A\u5DE5\u4F5C\u533A\uFF08\u9ED8\u8BA4\u76EE\u5F55\uFF09",
20240
20244
  "sched.workspaceHint": "\u6267\u884C\u65F6\u4F1A\u5728\u8FD9\u4E2A\u5DE5\u4F5C\u533A\u4E0B\u65B0\u5EFA\u4F1A\u8BDD\uFF0C\u5E76\u663E\u793A\u5728\u5DE5\u4F5C\u533A\u5206\u7EC4\u91CC\u3002",
20245
+ "sched.workspacePath": "\u76EE\u5F55\uFF1A{path}",
20246
+ "sched.workspaceCustom": "\uFF0B \u81EA\u5B9A\u4E49\u76EE\u5F55\u2026",
20247
+ "sched.workspaceCustomPlaceholder": "\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 /Users/\u4F60/tasks",
20248
+ "sched.workspaceCustomHint": "\u76EE\u5F55\u4E0D\u5B58\u5728\u65F6\u4F1A\u81EA\u52A8\u521B\u5EFA\uFF0C\u5E76\u6CE8\u518C\u6210\u4E00\u4E2A\u5DE5\u4F5C\u533A\u3002",
20249
+ "sched.workspaceCustomEmpty": "\u8BF7\u5148\u586B\u5199\u81EA\u5B9A\u4E49\u76EE\u5F55\u7684\u7EDD\u5BF9\u8DEF\u5F84\u3002",
20241
20250
  "sched.cronLabel": "cron \u5B9A\u65F6\u5668",
20242
20251
  "sched.cronHint": "\u4E94\u6BB5 croner \u8868\u8FBE\u5F0F\uFF08\u5206 \u65F6 \u65E5 \u6708 \u5468\uFF09\uFF0C\u4F8B\u5982 \u201C0 9 * * *\u201D \u8868\u793A\u6BCF\u5929 09:00\u3002",
20243
20252
  "sched.cronHourly": "\u6BCF\u5C0F\u65F6",
@@ -20494,6 +20503,11 @@ var en = {
20494
20503
  "sched.workspace": "Workspace",
20495
20504
  "sched.workspaceNone": "None (default directory)",
20496
20505
  "sched.workspaceHint": "Each run starts a new session in this workspace; sessions appear grouped under it in the sidebar.",
20506
+ "sched.workspacePath": "Directory: {path}",
20507
+ "sched.workspaceCustom": "+ Custom directory\u2026",
20508
+ "sched.workspaceCustomPlaceholder": "Absolute path, e.g. /Users/you/tasks",
20509
+ "sched.workspaceCustomHint": "The directory is created when missing, then registered as a workspace.",
20510
+ "sched.workspaceCustomEmpty": "Enter an absolute path for the custom directory first.",
20497
20511
  "sched.cronLabel": "Cron schedule",
20498
20512
  "sched.cronHint": 'Five-field cron expression (minute hour day month weekday), e.g. "0 9 * * *" runs daily at 09:00.',
20499
20513
  "sched.cronHourly": "Hourly",
@@ -20808,18 +20822,23 @@ button:has(.t-team-schedule-glyph):hover{background:var(--dsw-alias-button-float
20808
20822
  .t-team-sched-nextList{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
20809
20823
  .t-team-sched-nextList li{font-size:12px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:2px 8px;font-variant-numeric:tabular-nums}
20810
20824
  /* \u63D0\u793A\u8BCD\u8F93\u5165\u533A\uFF1A\u6846\u5185\u7B2C\u4E00\u884C\u662F\u4E13\u5BB6\u82AF\u7247\uFF08\u6807\u7B7E\u89C2\u611F\uFF0C\u4E0E\u5BF9\u8BDD\u8F93\u5165\u6846\u4E00\u81F4\uFF09\uFF0C\u4E0B\u9762\u662F\u6B63\u6587 */
20811
- .t-team-sched-promptbox{box-sizing:border-box;display:flex;flex-direction:column;gap:6px;padding:8px 10px;border-radius:8px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);transition:border-color .16s}
20825
+ .t-team-sched-promptbox{box-sizing:border-box;display:flex;flex-direction:column;padding:8px 10px;border-radius:8px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);transition:border-color .16s}
20812
20826
  .t-team-sched-promptbox:focus-within{border-color:var(--dsw-alias-brand-primary, var(--dsw-alias-label-primary))}
20813
- .t-team-sched-chips{display:flex;flex-wrap:wrap;gap:6px}
20814
- .t-team-sched-chip{display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:2px 4px 2px 8px;border-radius:999px;background:color-mix(in srgb, var(--dsw-alias-brand-primary, #1677ff) 12%, transparent);color:var(--dsw-alias-brand-primary, #1677ff);font-size:12px;line-height:18px}
20827
+ /* \u82AF\u7247\u89C2\u611F\u5BF9\u9F50\u5BF9\u8BDD\u8F93\u5165\u6846\u91CC\u7684\u5F15\u7528\u82AF\u7247\uFF1A\u6D45\u7070\u5E95\u3001\u5706\u89D2\u77E9\u5F62\uFF08\u4E0D\u662F\u5168\u80F6\u56CA\uFF09\u3001\u84DD\u8272\u6587\u5B57\u3001
20828
+ * \u5DE6\u4FA7\u4E00\u4E2A\u5706\u5F62\u7EBF\u6761\u5C0F\u56FE\u6807\uFF1B\xD7 \u5E73\u65F6\u4E0D\u663E\u793A\uFF0C\u60AC\u505C\u624D\u6D6E\u51FA\u6765\uFF08\u622A\u56FE\u91CC\u5C31\u662F\u6CA1\u6709 \xD7 \u7684\u6837\u5B50\uFF09\u3002 */
20829
+ .t-team-sched-chip{box-sizing:border-box;display:inline-flex;align-items:center;gap:3px;max-width:100%;margin:0 2px;padding:0 4px;border:1px solid transparent;border-radius:6px;background:color-mix(in srgb, var(--dsw-alias-label-primary) 10%, transparent);color:var(--dsw-alias-brand-primary, #1677ff);font-size:12px;line-height:18px;vertical-align:middle;user-select:none}
20830
+ /* \u60AC\u505C\u7ED9\u4E00\u5708\u6DE1\u63CF\u8FB9\uFF1A\u8BA9"\u9F20\u6807\u5728\u8FD9\u679A\u82AF\u7247\u4E0A"\u8FD9\u4EF6\u4E8B\u6709\u786E\u5B9A\u7684\u89C6\u89C9\u53CD\u9988\uFF08\u522B\u9760\u6D4F\u89C8\u5668\u9ED8\u8BA4\uFF09\u3002 */
20831
+ .t-team-sched-chip:hover{border-color:color-mix(in srgb, var(--dsw-alias-brand-primary, #1677ff) 35%, transparent)}
20832
+ .t-team-sched-chip-icon{flex:none;display:block}
20815
20833
  .t-team-sched-chip-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
20816
- .t-team-sched-chip-remove{padding:0 3px;border:0;background:transparent;color:inherit;font:inherit;font-size:13px;line-height:1;cursor:pointer;opacity:.7}
20817
- .t-team-sched-chip-remove:hover:not(:disabled){opacity:1}
20818
- .t-team-sched-chip-remove:disabled{opacity:.35;cursor:default}
20819
- /* \u26A0\uFE0F \u5FC5\u987B\u5E26 .t-team-sched-field \u524D\u7F00\uFF1A\u5426\u5219\u7279\u5F02\u6027\u4F4E\u4E8E\u901A\u7528\u7684 ".t-team-sched-field textarea" \u89C4\u5219\uFF0C
20820
- * \u6B63\u6587\u4F1A\u5E26\u7740\u81EA\u5DF1\u90A3\u5708\u8FB9\u6846\uFF0C\u89C6\u89C9\u4E0A\u53D8\u6210\u300C\u6846\u91CC\u5957\u6846\u300D\u3002 */
20821
- .t-team-sched-field .t-team-sched-prompt-input{box-sizing:border-box;width:100%;min-height:72px;padding:0;border:0;border-radius:0;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;resize:vertical}
20834
+ .t-team-sched-chip-remove{padding:0 1px;border:0;background:transparent;color:inherit;font:inherit;font-size:12px;line-height:1;cursor:pointer;opacity:.6;transition:opacity .12s}
20835
+ .t-team-sched-chip-remove:hover{opacity:1}
20836
+ /* \u63D0\u793A\u8BCD\u7F16\u8F91\u533A\uFF1Acontenteditable \u7684\u5BCC\u6587\u672C\u6D41\uFF08\u7EAF\u6587\u5B57 + \u82AF\u7247\uFF09\uFF0C\u82AF\u7247\u56E0\u6B64\u80FD\u63D2\u5728\u6B63\u6587\u4EFB\u610F\u4F4D\u7F6E\u3002
20837
+ * \u26A0\uFE0F \u7C7B\u540D\u5FC5\u987B\u5E26 .t-team-sched-field \u524D\u7F00\uFF1A\u5426\u5219\u7279\u5F02\u6027\u4F4E\u4E8E\u901A\u7528\u7684 ".t-team-sched-field textarea"
20838
+ * \u90A3\u7C7B\u89C4\u5219\uFF0C\u7F16\u8F91\u533A\u4F1A\u81EA\u5E26\u4E00\u5708\u8FB9\u6846\uFF08\u8E29\u8FC7\uFF1A\u6846\u91CC\u5957\u6846\uFF09\u3002 */
20839
+ .t-team-sched-field .t-team-sched-prompt-input{box-sizing:border-box;width:100%;min-height:72px;max-height:320px;overflow-y:auto;padding:0;border:0;border-radius:0;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:22px;white-space:pre-wrap;word-break:break-word;cursor:text;resize:none}
20822
20840
  .t-team-sched-field .t-team-sched-prompt-input:focus{outline:none;border:0}
20841
+ .t-team-sched-field .t-team-sched-prompt-input[data-empty="true"]::before{content:attr(data-placeholder);color:var(--dsw-alias-label-tertiary);pointer-events:none}
20823
20842
  /* \u63D0\u793A\u8BCD\u6846\u4E0B\u65B9\u7684\u300CT\u4E13\u5BB6\u300D\u6311\u9009\u5668\uFF1A\u6309\u94AE + \u53EA\u542B\u4E13\u5BB6\u5217\u8868\u7684\u6D6E\u5C42\uFF08\u7C7B\u540D\u72EC\u7ACB\uFF0C\u907F\u514D\u4E0E\u65E2\u6709\u7C7B\u4E92\u76F8\u8986\u76D6\uFF09 */
20824
20843
  .t-team-expert-pick{position:relative;display:flex;align-items:center;gap:8px;margin-top:2px}
20825
20844
  .t-team-expert-pick-hint{font-size:12px;color:var(--dsw-alias-label-secondary)}
@@ -20878,6 +20897,9 @@ var TYPERT_REMOTE = {
20878
20897
  direct("runScheduleItem", [
20879
20898
  { name: "id", wire: "id", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128) } }
20880
20899
  ], "TTeamSchedule", scheduleSnapshotSchema),
20900
+ direct("ensureScheduleWorkspace", [
20901
+ { name: "path", wire: "path", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().max(1024) } }
20902
+ ], "TTeamScheduleWorkspace", scheduleWorkspaceSchema),
20881
20903
  direct("previewSchedule", [
20882
20904
  { name: "cron", wire: "cron", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(120) } }
20883
20905
  ], "TTeamSchedulePreview", schedulePreviewSchema),
@@ -20941,11 +20963,7 @@ function onCatalogLoaded(listener) {
20941
20963
  catalogListeners.add(listener);
20942
20964
  return () => catalogListeners.delete(listener);
20943
20965
  }
20944
- async function refresh(remote, force = false) {
20945
- const cached2 = catalogCache.get(remote);
20946
- if (cached2 !== void 0 && !force) return cached2;
20947
- const next = unwrap(await remote.getCatalog(), "getCatalog");
20948
- next.enabledSet = new Set(next.enabled);
20966
+ function publishCatalog(remote, next) {
20949
20967
  catalogCache.set(remote, next);
20950
20968
  for (const listener of catalogListeners) {
20951
20969
  try {
@@ -20956,6 +20974,13 @@ async function refresh(remote, force = false) {
20956
20974
  }
20957
20975
  return next;
20958
20976
  }
20977
+ async function refresh(remote, force = false) {
20978
+ const cached2 = catalogCache.get(remote);
20979
+ if (cached2 !== void 0 && !force) return cached2;
20980
+ const next = unwrap(await remote.getCatalog(), "getCatalog");
20981
+ next.enabledSet = new Set(next.enabled);
20982
+ return publishCatalog(remote, next);
20983
+ }
20959
20984
  function displayName(expert, active) {
20960
20985
  return active === "en" ? expert.nameEn || expert.name : expert.name || expert.nameEn;
20961
20986
  }
@@ -20965,25 +20990,50 @@ function displayDescription(expert, active) {
20965
20990
  function divisionLabel(expert, active) {
20966
20991
  return active === "en" ? expert.divisionEn || expert.division : expert.divisionZh || expert.division;
20967
20992
  }
20968
- function splitExpertMentions(text, experts, active) {
20969
- let rest = String(text ?? "");
20970
- const mentions = [];
20971
- for (let step = 0; step < 32; step += 1) {
20972
- let matched;
20973
- for (const expert of experts ?? []) {
20974
- const names = [displayName(expert, active), expert?.name, expert?.nameEn, expert?.slug].filter((name) => typeof name === "string" && name !== "");
20975
- for (const name of names) {
20976
- if (!rest.startsWith(`@${name} `)) continue;
20977
- if (matched === void 0 || name.length > matched.name.length) {
20978
- matched = { name, display: displayName(expert, active) };
20979
- }
20993
+ function matchExpertAtHead(text, experts, active) {
20994
+ if (!text.startsWith("@")) return void 0;
20995
+ let matched;
20996
+ for (const expert of experts ?? []) {
20997
+ const names = [displayName(expert, active), expert?.name, expert?.nameEn, expert?.slug].filter((name) => typeof name === "string" && name !== "");
20998
+ for (const name of names) {
20999
+ if (!text.startsWith(`@${name}`)) continue;
21000
+ if (matched === void 0 || name.length > matched.name.length) {
21001
+ matched = { name, display: displayName(expert, active) };
20980
21002
  }
20981
21003
  }
20982
- if (matched === void 0) break;
20983
- rest = rest.slice(matched.name.length + 2);
20984
- if (!mentions.includes(matched.display)) mentions.push(matched.display);
20985
21004
  }
20986
- return { mentions, body: rest };
21005
+ return matched;
21006
+ }
21007
+ function tokenizePrompt(text, experts, active) {
21008
+ const raw = String(text ?? "");
21009
+ const tokens = [];
21010
+ let buffer = "";
21011
+ let rest = raw;
21012
+ const flush = () => {
21013
+ if (buffer === "") return;
21014
+ tokens.push({ type: "text", text: buffer });
21015
+ buffer = "";
21016
+ };
21017
+ while (rest !== "") {
21018
+ const hit = rest.startsWith("@") ? matchExpertAtHead(rest, experts, active) : void 0;
21019
+ if (hit === void 0) {
21020
+ buffer += rest[0];
21021
+ rest = rest.slice(1);
21022
+ continue;
21023
+ }
21024
+ flush();
21025
+ tokens.push({ type: "expert", name: hit.display });
21026
+ rest = rest.slice(hit.name.length + 1);
21027
+ }
21028
+ flush();
21029
+ return tokens;
21030
+ }
21031
+ function collectExpertMentions(text, experts, active) {
21032
+ const names = [];
21033
+ for (const token of tokenizePrompt(text, experts, active)) {
21034
+ if (token.type === "expert" && !names.includes(token.name)) names.push(token.name);
21035
+ }
21036
+ return names;
20987
21037
  }
20988
21038
  function matchExpert(expert, active, query) {
20989
21039
  if (query === "") return true;
@@ -21021,6 +21071,7 @@ var SectionBoundary = class extends import_react.default.Component {
21021
21071
  return this.props.children;
21022
21072
  }
21023
21073
  };
21074
+ var CUSTOM_WORKSPACE = "__custom__";
21024
21075
  var SCHEDULE_PANEL_KEY = `${NS}-schedule`;
21025
21076
  var SCHEDULE_PRESET_LABELS = {
21026
21077
  hourly: "sched.presetHourly",
@@ -21187,13 +21238,220 @@ function CronPicker({ t, remote, value, onChange, disabled }) {
21187
21238
  ), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-sum" }, hint === "" ? summary : hint), fires.length > 0 && /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-next" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-sched-nextLabel" }, t("sched.nextRuns", { n: fires.length })), /* @__PURE__ */ import_react.default.createElement("ul", { className: "t-team-sched-nextList" }, fires.map((iso, index) => /* @__PURE__ */ import_react.default.createElement("li", { key: index }, new Date(iso).toLocaleString(void 0, { weekday: "short", month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit" }))))));
21188
21239
  }
21189
21240
  function emptyScheduleForm() {
21190
- return { editingId: null, title: "", prompt: "", cron: "", enabled: true, workspaceId: "" };
21241
+ return { editingId: null, title: "", prompt: "", cron: "", enabled: true, workspaceId: "", customDir: "" };
21191
21242
  }
21192
21243
  function scheduleLastRun(t, item) {
21193
21244
  if (!item.lastRunAt) return t("sched.neverRun");
21194
21245
  const time3 = new Date(item.lastRunAt).toLocaleString();
21195
21246
  return item.lastRunError === void 0 ? time3 : `${time3}\uFF08${t("sched.failed")}: ${item.lastRunError}\uFF09`;
21196
21247
  }
21248
+ function PromptEditor({ editorRef, t, active, experts, value, disabled, onChange }) {
21249
+ const boxRef = import_react.default.useRef(null);
21250
+ const lastWritten = import_react.default.useRef(null);
21251
+ const savedRange = import_react.default.useRef(null);
21252
+ const buildChipIcon = () => {
21253
+ const NS2 = "http://www.w3.org/2000/svg";
21254
+ const svg = document.createElementNS(NS2, "svg");
21255
+ svg.setAttribute("class", "t-team-sched-chip-icon");
21256
+ svg.setAttribute("viewBox", "0 0 16 16");
21257
+ svg.setAttribute("width", "13");
21258
+ svg.setAttribute("height", "13");
21259
+ svg.setAttribute("fill", "none");
21260
+ svg.setAttribute("stroke", "currentColor");
21261
+ svg.setAttribute("stroke-width", "1.4");
21262
+ svg.setAttribute("stroke-linecap", "round");
21263
+ svg.setAttribute("aria-hidden", "true");
21264
+ const circle = document.createElementNS(NS2, "circle");
21265
+ circle.setAttribute("cx", "8");
21266
+ circle.setAttribute("cy", "8");
21267
+ circle.setAttribute("r", "6");
21268
+ const line1 = document.createElementNS(NS2, "line");
21269
+ line1.setAttribute("x1", "5.4");
21270
+ line1.setAttribute("y1", "6.6");
21271
+ line1.setAttribute("x2", "10.6");
21272
+ line1.setAttribute("y2", "6.6");
21273
+ const line2 = document.createElementNS(NS2, "line");
21274
+ line2.setAttribute("x1", "5.4");
21275
+ line2.setAttribute("y1", "9.4");
21276
+ line2.setAttribute("x2", "9");
21277
+ line2.setAttribute("y2", "9.4");
21278
+ svg.append(circle, line1, line2);
21279
+ return svg;
21280
+ };
21281
+ const buildChip = (name) => {
21282
+ const chip = document.createElement("span");
21283
+ chip.className = "t-team-sched-chip";
21284
+ chip.contentEditable = "false";
21285
+ chip.dataset.expert = name;
21286
+ const label = document.createElement("span");
21287
+ label.className = "t-team-sched-chip-name";
21288
+ label.textContent = name;
21289
+ const remove = document.createElement("button");
21290
+ remove.type = "button";
21291
+ remove.className = "t-team-sched-chip-remove";
21292
+ remove.dataset.remove = name;
21293
+ remove.textContent = "\xD7";
21294
+ remove.title = t("sched.expertRemove", { name });
21295
+ chip.append(buildChipIcon(), label, remove);
21296
+ return chip;
21297
+ };
21298
+ const serialize = () => {
21299
+ const box = boxRef.current;
21300
+ if (box === null) return "";
21301
+ let out = "";
21302
+ for (const node2 of box.childNodes) {
21303
+ if (node2.nodeType === 3) {
21304
+ out += node2.textContent ?? "";
21305
+ continue;
21306
+ }
21307
+ if (node2.nodeType !== 1) continue;
21308
+ const el = (
21309
+ /** @type {HTMLElement} */
21310
+ node2
21311
+ );
21312
+ if (el.dataset?.expert !== void 0) {
21313
+ out += `@${el.dataset.expert}`;
21314
+ continue;
21315
+ }
21316
+ if (el.tagName === "BR") {
21317
+ out += "\n";
21318
+ continue;
21319
+ }
21320
+ out += el.textContent ?? "";
21321
+ }
21322
+ return out;
21323
+ };
21324
+ const refreshEmpty = () => {
21325
+ const box = boxRef.current;
21326
+ if (box !== null) box.dataset.empty = box.textContent === "" ? "true" : "false";
21327
+ };
21328
+ const pushOut = () => {
21329
+ const text = serialize();
21330
+ lastWritten.current = text;
21331
+ refreshEmpty();
21332
+ onChange(text);
21333
+ };
21334
+ const rebuild = () => {
21335
+ const box = boxRef.current;
21336
+ if (box === null) return;
21337
+ box.textContent = "";
21338
+ for (const token of tokenizePrompt(value, experts, active)) {
21339
+ box.append(token.type === "text" ? document.createTextNode(token.text ?? "") : buildChip(token.name ?? ""));
21340
+ }
21341
+ refreshEmpty();
21342
+ };
21343
+ const removeExpert = (name) => {
21344
+ const box = boxRef.current;
21345
+ if (box === null) return;
21346
+ for (const el of box.querySelectorAll("[data-expert]")) {
21347
+ if (
21348
+ /** @type {HTMLElement} */
21349
+ el.dataset.expert === name
21350
+ ) {
21351
+ el.remove();
21352
+ break;
21353
+ }
21354
+ }
21355
+ pushOut();
21356
+ };
21357
+ const insertExpert = (name) => {
21358
+ const box = boxRef.current;
21359
+ if (box === null || disabled) return;
21360
+ const chip = buildChip(name);
21361
+ const space = document.createTextNode(" ");
21362
+ box.focus();
21363
+ const selection = window.getSelection();
21364
+ if (selection !== null && savedRange.current !== null && box.contains(savedRange.current.commonAncestorContainer)) {
21365
+ selection.removeAllRanges();
21366
+ selection.addRange(savedRange.current);
21367
+ }
21368
+ const inside = selection !== null && selection.rangeCount > 0 && box.contains(selection.anchorNode);
21369
+ if (inside) {
21370
+ const range = selection.getRangeAt(0);
21371
+ range.deleteContents();
21372
+ range.insertNode(chip);
21373
+ chip.after(space);
21374
+ range.setStartAfter(space);
21375
+ range.collapse(true);
21376
+ selection.removeAllRanges();
21377
+ selection.addRange(range);
21378
+ savedRange.current = range.cloneRange();
21379
+ } else {
21380
+ box.append(chip, space);
21381
+ }
21382
+ pushOut();
21383
+ };
21384
+ import_react.default.useEffect(() => {
21385
+ if (editorRef === void 0) return void 0;
21386
+ editorRef.current = { insertExpert, removeExpert, focus: () => boxRef.current?.focus() };
21387
+ return () => {
21388
+ editorRef.current = null;
21389
+ };
21390
+ });
21391
+ import_react.default.useEffect(() => {
21392
+ if (lastWritten.current === value) return;
21393
+ rebuild();
21394
+ }, [value, experts, active]);
21395
+ import_react.default.useEffect(() => {
21396
+ const onSelectionChange = () => {
21397
+ const box = boxRef.current;
21398
+ if (box === null) return;
21399
+ const selection = window.getSelection();
21400
+ if (selection === null || selection.rangeCount === 0) return;
21401
+ const range = selection.getRangeAt(0);
21402
+ if (box.contains(range.commonAncestorContainer)) savedRange.current = range.cloneRange();
21403
+ };
21404
+ document.addEventListener("selectionchange", onSelectionChange);
21405
+ return () => document.removeEventListener("selectionchange", onSelectionChange);
21406
+ }, []);
21407
+ const onPaste = (event) => {
21408
+ const text = event.clipboardData?.getData("text/plain") ?? "";
21409
+ if (text === "") return;
21410
+ event.preventDefault();
21411
+ const selection = window.getSelection();
21412
+ if (selection === null || selection.rangeCount === 0) return;
21413
+ const range = selection.getRangeAt(0);
21414
+ range.deleteContents();
21415
+ const node2 = document.createTextNode(text);
21416
+ range.insertNode(node2);
21417
+ range.setStartAfter(node2);
21418
+ range.collapse(true);
21419
+ selection.removeAllRanges();
21420
+ selection.addRange(range);
21421
+ pushOut();
21422
+ };
21423
+ return /* @__PURE__ */ import_react.default.createElement(
21424
+ "div",
21425
+ {
21426
+ ref: boxRef,
21427
+ className: "t-team-sched-prompt-input",
21428
+ contentEditable: !disabled,
21429
+ suppressContentEditableWarning: true,
21430
+ role: "textbox",
21431
+ "aria-multiline": "true",
21432
+ "aria-label": t("sched.promptLabel"),
21433
+ "data-placeholder": t("sched.promptPlaceholder"),
21434
+ "data-empty": "true",
21435
+ onInput: () => {
21436
+ if (!disabled) pushOut();
21437
+ },
21438
+ onPaste,
21439
+ onBlur: () => {
21440
+ if (!disabled) pushOut();
21441
+ },
21442
+ onMouseDownCapture: (event) => {
21443
+ const target = (
21444
+ /** @type {HTMLElement} */
21445
+ event.target
21446
+ );
21447
+ const name = target?.dataset?.remove;
21448
+ if (name === void 0 || disabled) return;
21449
+ event.preventDefault();
21450
+ removeExpert(name);
21451
+ }
21452
+ }
21453
+ );
21454
+ }
21197
21455
  function ExpertPicker({ t, active, experts, disabled, selected, onPick }) {
21198
21456
  const [open2, setOpen] = import_react.default.useState(false);
21199
21457
  const [query, setQuery] = import_react.default.useState("");
@@ -21277,6 +21535,7 @@ function ExpertPicker({ t, active, experts, disabled, selected, onPick }) {
21277
21535
  "data-picked": picked.includes(displayName(expert, active)),
21278
21536
  className: "t-team-expert-pick-item",
21279
21537
  onMouseEnter: () => setIndex(position),
21538
+ onMouseDown: (event) => event.preventDefault(),
21280
21539
  onClick: () => pick2(expert)
21281
21540
  },
21282
21541
  /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-expert-pick-name" }, picked.includes(displayName(expert, active)) ? "\u2713 " : "", expert.emoji, " ", displayName(expert, active)),
@@ -21293,6 +21552,8 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21293
21552
  const [historyId, setHistoryId] = import_react.default.useState(null);
21294
21553
  const [runningId, setRunningId] = import_react.default.useState(null);
21295
21554
  const [experts, setExperts] = import_react.default.useState([]);
21555
+ const promptEditorRef = import_react.default.useRef(null);
21556
+ const [extraWorkspaces, setExtraWorkspaces] = import_react.default.useState([]);
21296
21557
  const layout = () => hostCtx?.get?.("layout") ?? hostCtx?.layout;
21297
21558
  const backToConversation = () => layout()?.selectPanel?.(null);
21298
21559
  const load = import_react.default.useCallback(async () => {
@@ -21311,17 +21572,23 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21311
21572
  }, [load]);
21312
21573
  import_react.default.useEffect(() => {
21313
21574
  let alive = true;
21575
+ const sync = () => {
21576
+ const current = snapshotOf(remote);
21577
+ if (current === void 0 || !alive) return;
21578
+ setExperts(current.experts.filter((expert) => expert.conflict !== true && current.enabledSet.has(expert.slug)));
21579
+ };
21580
+ const stop = onCatalogLoaded(sync);
21314
21581
  void (async () => {
21315
21582
  try {
21316
- const catalogSnapshot = await refresh(remote);
21317
- if (!alive) return;
21318
- setExperts(catalogSnapshot.experts.filter((expert) => expert.conflict !== true && catalogSnapshot.enabledSet.has(expert.slug)));
21583
+ await refresh(remote);
21584
+ sync();
21319
21585
  } catch (cause) {
21320
21586
  console.warn("[t-team] \u5B9A\u65F6\u4EFB\u52A1\uFF1A\u8BFB\u53D6\u4E13\u5BB6\u540D\u518C\u5931\u8D25\uFF0C\u300CT\u4E13\u5BB6\u300D\u6311\u9009\u5668\u6682\u4E0D\u53EF\u7528\uFF1A", cause);
21321
21587
  }
21322
21588
  })();
21323
21589
  return () => {
21324
21590
  alive = false;
21591
+ stop();
21325
21592
  };
21326
21593
  }, [remote]);
21327
21594
  const active = getActive();
@@ -21334,13 +21601,28 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21334
21601
  setError("");
21335
21602
  };
21336
21603
  function fillExpert(expert) {
21604
+ const editor = promptEditorRef.current;
21605
+ if (editor === null) return;
21337
21606
  const name = displayName(expert, active);
21338
- setForm((current) => {
21339
- if (current === null) return current;
21340
- const { mentions, body } = splitExpertMentions(current.prompt, experts, active);
21341
- const next = mentions.includes(name) ? mentions.filter((item) => item !== name) : [...mentions, name];
21342
- return { ...current, prompt: `${next.map((item) => `@${item} `).join("")}${body}` };
21343
- });
21607
+ if (mentioned.includes(name)) editor.removeExpert(name);
21608
+ else editor.insertExpert(name);
21609
+ }
21610
+ function rememberWorkspace(workspace) {
21611
+ if (workspace === void 0 || workspace === null) return "";
21612
+ setExtraWorkspaces((current) => current.some((item) => item.id === workspace.id) ? current : [...current, workspace]);
21613
+ return workspace.id;
21614
+ }
21615
+ async function openNewForm() {
21616
+ setBusy(true);
21617
+ let workspaceId = "";
21618
+ try {
21619
+ workspaceId = rememberWorkspace(unwrap(await remote.ensureScheduleWorkspace(""), "ensureScheduleWorkspace")?.workspace);
21620
+ } catch (cause) {
21621
+ setError(errorText(cause));
21622
+ } finally {
21623
+ setBusy(false);
21624
+ }
21625
+ setForm({ ...emptyScheduleForm(), workspaceId });
21344
21626
  }
21345
21627
  async function submitForm() {
21346
21628
  if (form === null || busy) return;
@@ -21350,13 +21632,22 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21350
21632
  }
21351
21633
  setBusy(true);
21352
21634
  try {
21635
+ let workspaceId = form.workspaceId;
21636
+ if (workspaceId === CUSTOM_WORKSPACE) {
21637
+ const dir = form.customDir.trim();
21638
+ if (dir === "") {
21639
+ window.alert(t("sched.workspaceCustomEmpty"));
21640
+ return;
21641
+ }
21642
+ workspaceId = rememberWorkspace(unwrap(await remote.ensureScheduleWorkspace(dir), "ensureScheduleWorkspace")?.workspace);
21643
+ }
21353
21644
  const payload = {
21354
21645
  title: form.title.trim(),
21355
21646
  prompt: form.prompt,
21356
21647
  cron: form.cron.trim(),
21357
21648
  enabled: form.enabled,
21358
21649
  // 空串 = 不绑定工作区(显式解绑也走这个值,宿主认得)。
21359
- workspaceId: form.workspaceId === "" ? "" : form.workspaceId
21650
+ workspaceId: workspaceId === void 0 || workspaceId === null ? "" : workspaceId
21360
21651
  };
21361
21652
  const next = form.editingId === null ? unwrap(await remote.createScheduleItem(payload), "createScheduleItem") : unwrap(await remote.updateScheduleItem(form.editingId, payload), "updateScheduleItem");
21362
21653
  applySnapshot(next);
@@ -21390,7 +21681,11 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21390
21681
  }
21391
21682
  const items = snapshot?.items ?? [];
21392
21683
  const workspaces = snapshot?.workspaces ?? [];
21393
- const workspaceTitle = (id) => workspaces.find((workspace) => workspace.id === id)?.title ?? id;
21684
+ const allWorkspaces = [...workspaces];
21685
+ for (const workspace of extraWorkspaces) {
21686
+ if (!allWorkspaces.some((item) => item.id === workspace.id)) allWorkspaces.push(workspace);
21687
+ }
21688
+ const workspaceTitle = (id) => allWorkspaces.find((workspace) => workspace.id === id)?.title ?? id;
21394
21689
  const rowMeta = (item) => {
21395
21690
  const parts = [];
21396
21691
  if (item.workspaceId !== void 0) parts.push(`${t("sched.workspace")}: ${workspaceTitle(item.workspaceId)}`);
@@ -21399,23 +21694,8 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21399
21694
  return parts.join(" \xB7 ");
21400
21695
  };
21401
21696
  const disabled = busy || loading || !showButton;
21402
- const parsedPrompt = form === null ? { mentions: [], body: "" } : splitExpertMentions(form.prompt, experts, active);
21403
- const mentioned = parsedPrompt.mentions;
21404
- const promptBody = parsedPrompt.body;
21405
- function setPromptBody(nextBody) {
21406
- setForm((current) => {
21407
- if (current === null) return current;
21408
- const { mentions } = splitExpertMentions(current.prompt, experts, active);
21409
- return { ...current, prompt: `${mentions.map((item) => `@${item} `).join("")}${nextBody}` };
21410
- });
21411
- }
21412
- function removeExpert(name) {
21413
- setForm((current) => {
21414
- if (current === null) return current;
21415
- const { mentions, body } = splitExpertMentions(current.prompt, experts, active);
21416
- return { ...current, prompt: `${mentions.filter((item) => item !== name).map((item) => `@${item} `).join("")}${body}` };
21417
- });
21418
- }
21697
+ const mentioned = form === null ? [] : collectExpertMentions(form.prompt, experts, active);
21698
+ const selectedWorkspacePath = form === null ? "" : allWorkspaces.find((workspace) => workspace.id === form.workspaceId)?.path ?? "";
21419
21699
  return /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-head" }, /* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement("h2", { className: "t-team-sched-title" }, t("sched.title")), /* @__PURE__ */ import_react.default.createElement("p", { className: "t-team-sched-intro" }, t("sched.intro"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-actions" }, /* @__PURE__ */ import_react.default.createElement("button", { type: "button", className: "t-team-sched-btn", disabled: loading, onClick: () => void load() }, t("sched.refresh")), /* @__PURE__ */ import_react.default.createElement("button", { type: "button", className: "t-team-sched-btn", onClick: backToConversation }, t("sched.back")))), !showButton && /* @__PURE__ */ import_react.default.createElement("p", { className: "t-team-sched-note" }, t("sched.off")), snapshot !== null && snapshot.capabilities.agents !== true && /* @__PURE__ */ import_react.default.createElement("p", { className: "t-team-sched-note" }, t("sched.noAgents")), error62 !== "" && /* @__PURE__ */ import_react.default.createElement("p", { className: "t-team-sched-error", role: "alert" }, t("sched.error"), " ", error62, /* @__PURE__ */ import_react.default.createElement("button", { type: "button", className: "t-team-sched-btn", onClick: () => void load() }, t("sched.retry"))), loading && /* @__PURE__ */ import_react.default.createElement("p", { className: "t-team-sched-intro" }, t("sched.loading")), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-body" }, !loading && items.length === 0 && error62 === "" && /* @__PURE__ */ import_react.default.createElement("p", { className: "t-team-sched-intro" }, t("sched.empty")), /* @__PURE__ */ import_react.default.createElement("ul", { className: "t-team-sched-list" }, items.map((item) => /* @__PURE__ */ import_react.default.createElement("li", { key: item.id, className: "t-team-sched-row" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-rowMain" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-sched-rowTitle" }, item.title), /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-sched-rowCron" }, item.cron), /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-sched-rowMeta" }, rowMeta(item)), item.runs.length > 0 && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(
21420
21700
  "button",
21421
21701
  {
@@ -21446,11 +21726,12 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21446
21726
  prompt: item.prompt,
21447
21727
  cron: item.cron,
21448
21728
  enabled: item.enabled === true,
21449
- workspaceId: item.workspaceId ?? ""
21729
+ workspaceId: item.workspaceId ?? "",
21730
+ customDir: ""
21450
21731
  })
21451
21732
  },
21452
21733
  t("sched.edit")
21453
- ), /* @__PURE__ */ import_react.default.createElement("button", { type: "button", className: "t-team-sched-btn t-team-sched-btn-danger", disabled, onClick: () => void removeItem(item.id) }, t("sched.delete")))))), form === null ? /* @__PURE__ */ import_react.default.createElement("button", { type: "button", className: "t-team-sched-btn t-team-sched-btn-primary", disabled, onClick: () => setForm(emptyScheduleForm()) }, t("sched.new")) : /* @__PURE__ */ import_react.default.createElement(
21734
+ ), /* @__PURE__ */ import_react.default.createElement("button", { type: "button", className: "t-team-sched-btn t-team-sched-btn-danger", disabled, onClick: () => void removeItem(item.id) }, t("sched.delete")))))), form === null ? /* @__PURE__ */ import_react.default.createElement("button", { type: "button", className: "t-team-sched-btn t-team-sched-btn-primary", disabled, onClick: () => void openNewForm() }, t("sched.new")) : /* @__PURE__ */ import_react.default.createElement(
21454
21735
  "form",
21455
21736
  {
21456
21737
  className: "t-team-sched-form",
@@ -21469,26 +21750,16 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21469
21750
  onChange: (event) => setForm({ ...form, title: event.target.value })
21470
21751
  }
21471
21752
  )),
21472
- /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react.default.createElement("span", null, t("sched.promptLabel")), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-promptbox" }, mentioned.length > 0 && /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-chips" }, mentioned.map((name) => /* @__PURE__ */ import_react.default.createElement("span", { key: name, className: "t-team-sched-chip" }, /* @__PURE__ */ import_react.default.createElement("span", { "aria-hidden": "true" }, "\u{1F9E9}"), /* @__PURE__ */ import_react.default.createElement("span", { className: "t-team-sched-chip-name" }, name), /* @__PURE__ */ import_react.default.createElement(
21473
- "button",
21753
+ /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react.default.createElement("span", null, t("sched.promptLabel")), /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-promptbox" }, /* @__PURE__ */ import_react.default.createElement(
21754
+ PromptEditor,
21474
21755
  {
21475
- type: "button",
21476
- className: "t-team-sched-chip-remove",
21477
- disabled: busy,
21478
- title: t("sched.expertRemove", { name }),
21479
- "aria-label": t("sched.expertRemove", { name }),
21480
- onClick: () => removeExpert(name)
21481
- },
21482
- "\xD7"
21483
- )))), /* @__PURE__ */ import_react.default.createElement(
21484
- "textarea",
21485
- {
21486
- className: "t-team-sched-prompt-input",
21487
- value: promptBody,
21488
- rows: 4,
21756
+ editorRef: promptEditorRef,
21757
+ t,
21758
+ active,
21759
+ experts,
21760
+ value: form.prompt,
21489
21761
  disabled: busy,
21490
- placeholder: t("sched.promptPlaceholder"),
21491
- onChange: (event) => setPromptBody(event.target.value)
21762
+ onChange: (prompt) => setForm((current) => current === null ? current : { ...current, prompt })
21492
21763
  }
21493
21764
  )), /* @__PURE__ */ import_react.default.createElement(
21494
21765
  ExpertPicker,
@@ -21502,7 +21773,7 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21502
21773
  }
21503
21774
  ), mentioned.length > 0 && /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-expert-pick-hint" }, mentioned.length === 1 ? t("sched.expertInvokeHint", { name: mentioned[0] }) : t("sched.expertInvokeManyHint", { names: mentioned.join(t("sched.listSep")) }))),
21504
21775
  /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react.default.createElement("span", null, t("sched.cronLabel")), /* @__PURE__ */ import_react.default.createElement(CronPicker, { t, remote, value: form.cron, disabled: busy, onChange: (cron) => setForm((current) => current === null ? current : { ...current, cron }) }), /* @__PURE__ */ import_react.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.cronHint"))),
21505
- workspaces.length > 0 && /* @__PURE__ */ import_react.default.createElement("label", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react.default.createElement("span", null, t("sched.workspace")), /* @__PURE__ */ import_react.default.createElement(
21776
+ /* @__PURE__ */ import_react.default.createElement("div", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react.default.createElement("span", null, t("sched.workspace")), /* @__PURE__ */ import_react.default.createElement(
21506
21777
  "select",
21507
21778
  {
21508
21779
  value: form.workspaceId,
@@ -21510,8 +21781,18 @@ function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
21510
21781
  onChange: (event) => setForm({ ...form, workspaceId: event.target.value })
21511
21782
  },
21512
21783
  /* @__PURE__ */ import_react.default.createElement("option", { value: "" }, t("sched.workspaceNone")),
21513
- workspaces.map((workspace) => /* @__PURE__ */ import_react.default.createElement("option", { key: workspace.id, value: workspace.id }, workspace.title))
21514
- ), /* @__PURE__ */ import_react.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.workspaceHint"))),
21784
+ allWorkspaces.map((workspace) => /* @__PURE__ */ import_react.default.createElement("option", { key: workspace.id, value: workspace.id }, workspace.title)),
21785
+ form.workspaceId !== "" && form.workspaceId !== CUSTOM_WORKSPACE && !allWorkspaces.some((workspace) => workspace.id === form.workspaceId) && /* @__PURE__ */ import_react.default.createElement("option", { value: form.workspaceId }, form.workspaceId),
21786
+ /* @__PURE__ */ import_react.default.createElement("option", { value: CUSTOM_WORKSPACE }, t("sched.workspaceCustom"))
21787
+ ), form.workspaceId === CUSTOM_WORKSPACE ? /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(
21788
+ "input",
21789
+ {
21790
+ value: form.customDir,
21791
+ disabled: busy,
21792
+ placeholder: t("sched.workspaceCustomPlaceholder"),
21793
+ onChange: (event) => setForm({ ...form, customDir: event.target.value })
21794
+ }
21795
+ ), /* @__PURE__ */ import_react.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.workspaceCustomHint"))) : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.workspaceHint")), selectedWorkspacePath !== "" && /* @__PURE__ */ import_react.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.workspacePath", { path: selectedWorkspacePath })))),
21515
21796
  /* @__PURE__ */ import_react.default.createElement("label", { className: "t-team-sched-checkbox" }, /* @__PURE__ */ import_react.default.createElement(
21516
21797
  "input",
21517
21798
  {
@@ -21741,7 +22022,7 @@ function SettingsPanel({ t, ctx, remote, getActive, refreshCatalog, initialTab,
21741
22022
  setSnapshot({ ...snapshot, enabled: list });
21742
22023
  try {
21743
22024
  const state = unwrap(await remote.setEnabled(list, snapshot.revision), "setEnabled");
21744
- catalogCache.set(remote, { ...snapshot, enabled: state.enabled, enabledSet: new Set(state.enabled), revision: state.revision });
22025
+ publishCatalog(remote, { ...snapshot, enabled: state.enabled, enabledSet: new Set(state.enabled), revision: state.revision });
21745
22026
  setSnapshot({ ...snapshot, enabled: state.enabled, revision: state.revision });
21746
22027
  setError("");
21747
22028
  } catch (cause) {