dsh-composer-ux 0.5.0 → 0.6.2

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
@@ -105,7 +105,6 @@ var PANEL_ENABLED_FIELD = "panelEnabled";
105
105
  var TERMINAL_ENABLED_FIELD = "terminalEnabled";
106
106
  var SEND_KEY_FIELD = "sendKey";
107
107
  var NEWLINE_KEY_FIELD = "newlineKey";
108
- var PANEL_SCROLL_FIELD = "panelScroll";
109
108
  var PANEL_RESIZE_FIELD = "panelResize";
110
109
  var PANEL_WIDTH_FIELD = "panelWidth";
111
110
  var PANEL_HEIGHT_FIELD = "panelHeight";
@@ -165,11 +164,21 @@ function insertModeOf(prompt) {
165
164
  return "never";
166
165
  }
167
166
  var OPTIMIZER_TIERS = [
168
- { id: "basic", label: "\u666E\u901A", hint: "\u53EA\u505A\u8BED\u8A00\u5C42\u4FEE\u590D\uFF1A\u75C5\u53E5\u3001\u9519\u522B\u5B57\u3001\u6307\u4EE3\u4E0E\u542B\u7CCA\u8BCD\uFF0C\u4E0D\u65B0\u589E\u4EFB\u4F55\u9700\u6C42\uFF0C\u7BC7\u5E45\u4E0E\u539F\u6587\u76F8\u5F53\u3002" },
169
- { id: "advanced", label: "\u9AD8\u7EA7", hint: "\u5728\u4E0D\u52A8\u76EE\u6807\u7684\u524D\u63D0\u4E0B\uFF0C\u628A\u300C\u4F60\u663E\u7136\u60F3\u8981\u3001\u4F46\u6CA1\u8BF4\u51FA\u53E3\u300D\u7684\u5FC5\u8981\u8981\u6C42\u8865\u6210\u5BF9 AI \u7684\u8981\u6C42\uFF0C\u8BA9\u5B83\u4E00\u6B21\u505A\u5BF9\u3002" },
170
- { id: "extreme", label: "\u6781\u7AEF", hint: "\u6309\u590D\u6742\u4EFB\u52A1\u5904\u7406\uFF1A\u56FA\u5316\u547D\u4EE4\u7ED3\u6784 + \u5206\u9636\u6BB5\u6267\u884C\u8BA1\u5212 + 2~4 \u79CD\u60C5\u51B5\u7684\u9884\u6848\u3002" }
167
+ { id: "basic", label: "\u666E\u901A", hint: "\u53EA\u505A\u8BED\u8A00\u5C42\u4FEE\u590D\uFF1A\u75C5\u53E5\u3001\u9519\u522B\u5B57\u3001\u6307\u4EE3\u4E0E\u542B\u7CCA\u8BCD\uFF0C\u4E0D\u65B0\u589E\u4EFB\u4F55\u9700\u6C42\uFF0C\u7BC7\u5E45\u7EA6\u4E3A\u539F\u6587 1.4 \u500D\u3002" },
168
+ { id: "advanced", label: "\u9AD8\u7EA7", hint: "\u5728\u4E0D\u52A8\u76EE\u6807\u7684\u524D\u63D0\u4E0B\uFF0C\u628A\u300C\u4F60\u663E\u7136\u60F3\u8981\u3001\u4F46\u6CA1\u8BF4\u51FA\u53E3\u300D\u7684\u5FC5\u8981\u8981\u6C42\u8865\u6210\u5BF9 AI \u7684\u8981\u6C42\uFF0C\u6BCF\u6761\u90FD\u8981\u6307\u56DE\u4F60\u539F\u8BDD\u91CC\u7684\u67D0\u4E00\u53E5\u3002" },
169
+ { id: "extreme", label: "\u6781\u7AEF", hint: "\u6309\u590D\u6742\u4EFB\u52A1\u5904\u7406\uFF1A\u5728\u4E0A\u9762\u57FA\u7840\u4E0A\u518D\u52A0\u5206\u9636\u6BB5\u6267\u884C\u8BA1\u5212\u4E0E 2~4 \u79CD\u60C5\u51B5\u7684\u9884\u6848\u3002" }
171
170
  ];
172
171
  var DEFAULT_OPTIMIZER_TIER = "advanced";
172
+ var OPTIMIZER_PROMPT_FIELDS = {
173
+ basic: "optimizerPromptBasic",
174
+ advanced: "optimizerPromptAdvanced",
175
+ extreme: "optimizerPromptExtreme"
176
+ };
177
+ var OPTIMIZER_PROMPT_FIELD_LIST = OPTIMIZER_TIERS.map((item) => OPTIMIZER_PROMPT_FIELDS[item.id]);
178
+ var OPTIMIZER_PROMPT_MAX = 2e4;
179
+ function optimizerPromptFieldOf(tier) {
180
+ return OPTIMIZER_PROMPT_FIELDS[tier] ?? OPTIMIZER_PROMPT_FIELDS[DEFAULT_OPTIMIZER_TIER];
181
+ }
173
182
  var DEFAULT_QUICK_PROMPTS = [
174
183
  { id: "builtin-1", label: "\u4E00\u95EE\u4E00\u7B54", prompt: "\u4F60\u4E0D\u61C2\u7684\u5C31\u95EE\u6211\uFF0C\u4E00\u95EE\u4E00\u7B54\uFF1B\u540C\u65F6\u8BF4\u6E05\u695A\u4F60\u4E3A\u4EC0\u4E48\u8981\u95EE\u8BE5\u95EE\u9898\uFF1B\u76F4\u5230\u4F60\u5BF9\u6211\u7684\u76EE\u6807\u6709\u660E\u786E\u8BA4\u77E5\u540E\u518D\u5F00\u59CB\u5E72\u6D3B\u3002", always: false, firstOnly: false },
175
184
  { id: "builtin-2", label: "\u4EA4\u63A5\u6587\u6863", prompt: "\u628A\u8FD9\u6B21\u4EFB\u52A1\u3001\u5DF2\u5B8C\u6210\u5185\u5BB9\u3001\u5F53\u524D\u5361\u70B9\u3001\u4E0B\u4E00\u6B65\u8BA1\u5212\u3001\u8E29\u8FC7\u7684\u5751\uFF0C\u6574\u7406\u6210\u4E00\u4EFD\u4EA4\u63A5\u6587\u6863\uFF0C\u5199\u7ED9\u65B0\u4F1A\u8BDD\u770B\u3002", always: false, firstOnly: false },
@@ -307,7 +316,6 @@ var DEFAULT_SETTINGS = {
307
316
  menuDelete: true,
308
317
  menuSelectAll: true,
309
318
  menuMode: "official",
310
- panelScroll: true,
311
319
  panelResize: true,
312
320
  headerEnabled: false,
313
321
  headerName: DEFAULT_HEADER_NAME,
@@ -318,6 +326,10 @@ var DEFAULT_SETTINGS = {
318
326
  headerStatus: "",
319
327
  quickPrompts: DEFAULT_QUICK_PROMPTS,
320
328
  optimizerTier: DEFAULT_OPTIMIZER_TIER,
329
+ // 空串 = 用内置提示词。默认必须是空串:它同时就是「恢复内置」要写回去的值。
330
+ optimizerPromptBasic: "",
331
+ optimizerPromptAdvanced: "",
332
+ optimizerPromptExtreme: "",
321
333
  terminalMode: DEFAULT_TERMINAL_MODE,
322
334
  terminalBashPath: "",
323
335
  terminalCandidates: [],
@@ -361,7 +373,7 @@ var SECTION_SIGNALS = {
361
373
  // (`menuModeFrom` 对"两个键都没有"给的就是 'official',天然满足"缺省 = 默认"。)
362
374
  [MENU_ENABLED_FIELD]: (source) => menuModeFrom(source[MENU_MODE_FIELD], source[MENU_NATIVE_FIELD]) !== "official",
363
375
  [QUICK_ENABLED_FIELD]: (source) => Array.isArray(source[QUICK_PROMPTS_FIELD]) && source[QUICK_PROMPTS_FIELD].length !== DEFAULT_QUICK_PROMPTS.length || touched(source, OPTIMIZER_TIER_FIELD, DEFAULT_OPTIMIZER_TIER),
364
- [PANEL_ENABLED_FIELD]: (source) => touched(source, PANEL_SCROLL_FIELD, true) || touched(source, PANEL_RESIZE_FIELD, true) || source[PANEL_WIDTH_FIELD] !== void 0 || source[PANEL_HEIGHT_FIELD] !== void 0,
376
+ [PANEL_ENABLED_FIELD]: (source) => touched(source, PANEL_RESIZE_FIELD, true) || source[PANEL_WIDTH_FIELD] !== void 0 || source[PANEL_HEIGHT_FIELD] !== void 0,
365
377
  [TERMINAL_ENABLED_FIELD]: (source) => touched(source, TERMINAL_MODE_FIELD, DEFAULT_TERMINAL_MODE) || touched(source, TERMINAL_BASH_PATH_FIELD, "")
366
378
  };
367
379
  function touched(source, field, untouched) {
@@ -384,6 +396,10 @@ function sanitizeSettings(value) {
384
396
  const v = source[field];
385
397
  return typeof v === "string" && v.length <= max ? v : "";
386
398
  };
399
+ const asPrompt = (field, max) => {
400
+ const v = source[field];
401
+ return typeof v === "string" ? v.slice(0, max) : "";
402
+ };
387
403
  const asBool = (field) => {
388
404
  const v = source[field];
389
405
  return typeof v === "boolean" ? v : DEFAULT_SETTINGS[field];
@@ -439,7 +455,6 @@ function sanitizeSettings(value) {
439
455
  menuDelete: asBool("menuDelete"),
440
456
  menuSelectAll: asBool("menuSelectAll"),
441
457
  menuMode: menuModeFrom(source[MENU_MODE_FIELD], source[MENU_NATIVE_FIELD]),
442
- panelScroll: asBool(PANEL_SCROLL_FIELD),
443
458
  panelResize: asBool(PANEL_RESIZE_FIELD),
444
459
  panelWidth: asSize(PANEL_WIDTH_FIELD),
445
460
  panelHeight: asSize(PANEL_HEIGHT_FIELD),
@@ -454,6 +469,9 @@ function sanitizeSettings(value) {
454
469
  headerStatus: asText(HEADER_STATUS_FIELD, HEADER_VALUE_MAX),
455
470
  quickPrompts: asQuickPrompts(),
456
471
  optimizerTier: asTier(),
472
+ optimizerPromptBasic: asPrompt(OPTIMIZER_PROMPT_FIELDS.basic, OPTIMIZER_PROMPT_MAX),
473
+ optimizerPromptAdvanced: asPrompt(OPTIMIZER_PROMPT_FIELDS.advanced, OPTIMIZER_PROMPT_MAX),
474
+ optimizerPromptExtreme: asPrompt(OPTIMIZER_PROMPT_FIELDS.extreme, OPTIMIZER_PROMPT_MAX),
457
475
  terminalMode: terminalModeFrom(source[TERMINAL_MODE_FIELD]),
458
476
  // 路径只做长度与归一化收窄,不在这里判"存不存在"——那是宿主半的探测结论,
459
477
  // 由状态行告诉用户(用户看得见自己填了什么,比悄悄清空好)。
@@ -809,6 +827,24 @@ function sendButtonOf(target) {
809
827
  if (last.querySelector("svg path") === null) return null;
810
828
  return last;
811
829
  }
830
+ function droppedOf(value) {
831
+ if (!Array.isArray(value)) return [];
832
+ const out = [];
833
+ for (const entry of value) {
834
+ if (typeof entry !== "object" || entry === null) continue;
835
+ const row2 = entry;
836
+ out.push({
837
+ id: typeof row2.id === "string" ? row2.id : "",
838
+ kind: typeof row2.kind === "string" ? row2.kind : "",
839
+ reason: typeof row2.reason === "string" ? row2.reason : ""
840
+ });
841
+ }
842
+ return out;
843
+ }
844
+ function warningsOf(value) {
845
+ if (!Array.isArray(value)) return [];
846
+ return value.filter((entry) => typeof entry === "string");
847
+ }
812
848
  async function optimizeDraft(text, tier) {
813
849
  const body = text.trim();
814
850
  if (body === "") return { ok: false, error: "\u8F93\u5165\u6846\u662F\u7A7A\u7684\uFF0C\u5148\u5199\u70B9\u4EC0\u4E48\u518D\u4F18\u5316" };
@@ -832,14 +868,26 @@ async function optimizeDraft(text, tier) {
832
868
  return { ok: false, error: "\u5BBF\u4E3B\u534A\u8FD4\u56DE\u7684\u4E0D\u662F JSON" };
833
869
  }
834
870
  const record = typeof payload === "object" && payload !== null ? payload : {};
871
+ const retried = record.retried === true;
835
872
  if (record.ok !== true) {
836
873
  const message = typeof record.error === "string" && record.error !== "" ? record.error : "\u4F18\u5316\u5931\u8D25";
837
- return { ok: false, error: message };
874
+ return { ok: false, error: message, retried };
838
875
  }
839
876
  const optimized = typeof record.text === "string" ? record.text.trim() : "";
840
- if (optimized === "") return { ok: false, error: "\u6A21\u578B\u6CA1\u6709\u4EA7\u51FA\u4EFB\u4F55\u5185\u5BB9" };
877
+ if (optimized === "") return { ok: false, error: "\u6A21\u578B\u6CA1\u6709\u4EA7\u51FA\u4EFB\u4F55\u5185\u5BB9", retried };
841
878
  const route = `${String(record.provider ?? "")}/${String(record.model ?? "")}`;
842
- return { ok: true, text: optimized, route };
879
+ return {
880
+ ok: true,
881
+ text: optimized,
882
+ route,
883
+ itemCount: typeof record.itemCount === "number" ? record.itemCount : 0,
884
+ dropped: droppedOf(record.dropped),
885
+ warnings: warningsOf(record.warnings),
886
+ fallback: record.fallback === true,
887
+ retried,
888
+ promptSource: typeof record.promptSource === "string" ? record.promptSource : "",
889
+ rewrittenChars: typeof record.rewrittenChars === "number" ? record.rewrittenChars : 0
890
+ };
843
891
  }
844
892
 
845
893
  // src/client/interceptors.ts
@@ -1085,29 +1133,6 @@ var RESIZE_OUTLINE_STYLE = {
1085
1133
  border: "1px solid rgba(127, 127, 137, .28)",
1086
1134
  pointerEvents: "none"
1087
1135
  };
1088
- var PANEL_CSS = `
1089
- html.dsh-ux-panel-scroll [role="dialog"][aria-modal="true"]:has(> nav) { min-height: 320px; }
1090
- html.dsh-ux-panel-scroll [role="dialog"][aria-modal="true"]:has(> nav) > nav {
1091
- min-height: 0;
1092
- }
1093
- html.dsh-ux-panel-scroll [role="dialog"][aria-modal="true"]:has(> nav) > nav > div:last-child {
1094
- flex: 1 1 auto;
1095
- min-height: 0;
1096
- overflow-y: auto;
1097
- overscroll-behavior: contain;
1098
- scrollbar-width: thin;
1099
- }
1100
- html.dsh-ux-panel-scroll [role="dialog"][aria-modal="true"]:has(> nav) > nav > div:last-child::-webkit-scrollbar {
1101
- width: 8px;
1102
- }
1103
- html.dsh-ux-panel-scroll [role="dialog"][aria-modal="true"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb {
1104
- background: var(--dsh-scrollbar-thumb, var(--dsw-alias-scrollbar-bg-l2));
1105
- border-radius: 8px;
1106
- }
1107
- html.dsh-ux-panel-scroll [role="dialog"][aria-modal="true"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb:hover {
1108
- background: var(--dsh-scrollbar-thumb-hover, var(--dsw-alias-scrollbar-hover-l2));
1109
- }
1110
- `;
1111
1136
  var RESIZE_CSS = `
1112
1137
  .${RESIZE_LAYER_CLASS} { position: absolute; inset: 0; pointer-events: none; }
1113
1138
  .${RESIZE_EDGE_CLASS}, .${RESIZE_GRIP_CLASS} {
@@ -1129,21 +1154,13 @@ var RESIZE_CSS = `
1129
1154
  }
1130
1155
  .${RESIZE_GRIP_CLASS}:hover { color: rgba(127, 127, 137, .95); background: rgba(127, 127, 137, .16); }
1131
1156
  `;
1132
- function installPanelStyle(settings, subscribe) {
1157
+ function installPanelResizeStyle() {
1133
1158
  const tag = document.createElement("style");
1134
1159
  tag.dataset.plugin = "dsh-composer-ux-panel";
1135
- tag.textContent = `${PANEL_CSS}
1136
- ${RESIZE_CSS}`;
1160
+ tag.textContent = RESIZE_CSS;
1137
1161
  document.head.appendChild(tag);
1138
- const applyClass = () => {
1139
- document.documentElement.classList.toggle("dsh-ux-panel-scroll", settings());
1140
- };
1141
- applyClass();
1142
- const unsubscribe = subscribe(applyClass);
1143
1162
  return () => {
1144
- unsubscribe();
1145
1163
  tag.remove();
1146
- document.documentElement.classList.remove("dsh-ux-panel-scroll");
1147
1164
  };
1148
1165
  }
1149
1166
  function findSettingsPanel() {
@@ -1497,12 +1514,16 @@ var hintInfo = {
1497
1514
  };
1498
1515
  var menu = {
1499
1516
  position: "fixed",
1517
+ // 官方浮层用 1100,这里**刻意保留 9999**:本插件的浮层挂在 `shell.overlay` 这个
1518
+ // 独立层叠上下文里,要和别的插件抢层,降下去只会被盖住(见 panel.ts 文件头)。
1500
1519
  zIndex: 9999,
1501
1520
  minWidth: 200,
1502
1521
  background: "var(--dsw-specific-menu)",
1503
- border: "0.5px solid var(--dsw-alias-border-l1)",
1504
- borderRadius: 10,
1522
+ backdropFilter: "var(--dsw-menu-backdrop-filter)",
1523
+ border: 0,
1524
+ borderRadius: "var(--dsw-radius-lg)",
1505
1525
  boxShadow: "var(--dsw-elevation-prominent)",
1526
+ "--dsw-elevation-stroke-color": "var(--dsw-alias-border-l1)",
1506
1527
  padding: 5,
1507
1528
  pointerEvents: "auto",
1508
1529
  userSelect: "none"
@@ -1545,6 +1566,7 @@ var menuNote = {
1545
1566
  };
1546
1567
  var quickPanel = {
1547
1568
  position: "fixed",
1569
+ // 同 `menu`:刻意保留 9999,理由见那里。
1548
1570
  zIndex: 9999,
1549
1571
  width: 420,
1550
1572
  maxWidth: "calc(100vw - 24px)",
@@ -1552,9 +1574,11 @@ var quickPanel = {
1552
1574
  display: "flex",
1553
1575
  flexDirection: "column",
1554
1576
  background: "var(--dsw-specific-menu)",
1555
- border: "0.5px solid var(--dsw-alias-border-l1)",
1556
- borderRadius: 12,
1577
+ backdropFilter: "var(--dsw-menu-backdrop-filter)",
1578
+ border: 0,
1579
+ borderRadius: "var(--dsw-radius-lg)",
1557
1580
  boxShadow: "var(--dsw-elevation-prominent)",
1581
+ "--dsw-elevation-stroke-color": "var(--dsw-alias-border-l1)",
1558
1582
  pointerEvents: "auto",
1559
1583
  overflow: "hidden"
1560
1584
  };
@@ -2165,8 +2189,182 @@ function AddPromptRow({
2165
2189
  ] });
2166
2190
  }
2167
2191
 
2168
- // src/client/PillChoice.tsx
2192
+ // src/optimizer-prompt.ts
2193
+ var RELAY_ROLE = [
2194
+ '\u3010\u4F60\u662F\u8C01\u3011\u4F60\u662F\u4E00\u4E2A**\u4F20\u8BDD\u5668/\u610F\u56FE\u8865\u5168\u5668**\uFF0C\u7AD9\u5728\u7528\u6237\u4E0E"\u5DE5\u4F5C AI"\u4E4B\u95F4\uFF1A',
2195
+ " \u7528\u6237 \u2192\uFF08\u4F60\uFF1A\u628A\u7528\u6237\u7684\u610F\u601D\u6574\u7406\u6210\u6761\u76EE\u5E76\u7ED9\u51FA\u9010\u5B57\u4F9D\u636E\uFF09\u2192 \u5BBF\u4E3B\uFF08\u88C5\u914D\u6210\u4E00\u6761\u547D\u4EE4\uFF09\u2192 \u5DE5\u4F5C AI\u3002",
2196
+ "\u4F60\u7684\u4EA7\u51FA**\u4E0D\u4F1A**\u88AB\u76F4\u63A5\u5C55\u793A\u7ED9\u7528\u6237\uFF0C\u4E5F\u4E0D\u4F1A\u88AB\u539F\u6837\u53D1\u51FA\uFF1A\u5BBF\u4E3B\u4F1A\u7528\u4F60\u7ED9\u7684**\u9010\u5B57\u5F15\u6587**",
2197
+ "\u5728\u539F\u8BDD\u91CC\u5B9A\u4F4D\u3001\u53EA\u91C7\u7EB3\u80FD\u6838\u5BF9\u7684\u6761\u76EE\uFF0C\u518D\u88C5\u914D\u6210\u4E00\u6761\u547D\u4EE4\u4EA4\u7ED9\u5DE5\u4F5C AI\u3002",
2198
+ "\u3010\u4F60\u4E0D\u662F\u8C01\u3011\u4F60\u4E0D\u662F\u5728\u548C\u7528\u6237\u804A\u5929\uFF0C\u4E5F\u4E0D\u662F\u5728\u56DE\u7B54\u7528\u6237\uFF1A",
2199
+ "- \u4E0D\u8981\u56DE\u5E94\u3001\u4E0D\u8981\u56DE\u7B54\u7528\u6237\u7684\u8981\u6C42\uFF0C\u4E5F\u4E0D\u8981\u66FF\u7528\u6237\u5B8C\u6210\u4EFB\u52A1\uFF08\u4E0D\u8981\u76F4\u63A5\u7ED9\u51FA\u4EE3\u7801/\u7B54\u6848/\u7ED3\u679C\uFF09\u3002",
2200
+ '- \u4E0D\u8981\u4EE5\u52A9\u624B\u53E3\u543B\u5BF9\u7528\u6237\u8BF4\u8BDD\uFF08"\u597D\u7684""\u6536\u5230""\u6211\u53EF\u4EE5\u5E2E\u4F60""\u5EFA\u8BAE\u4F60\u2026""\u9700\u8981\u6211\u2026\u5417"\uFF09\u3002',
2201
+ '- \u4E0D\u8981\u628A\u7528\u6237\u53D1\u6765\u7684\u6587\u5B57\u5F53\u6210"\u5BF9\u4F60\u8BF4\u7684\u8BDD"\u6765\u56DE\u5E94\uFF1B\u5B83\u53EA\u662F\u4F60\u8981\u8F6C\u8FBE\u7684\u5185\u5BB9\u3002',
2202
+ "- \u4E0D\u8981\u5411\u7528\u6237\u63D0\u95EE\u3002\u8981\u6F84\u6E05\u65F6\uFF0C\u5199\u6210**\u7ED9\u5DE5\u4F5C AI \u7684\u6307\u4EE4**\uFF1A",
2203
+ ' "\u82E5 X \u4E0D\u660E\u786E\uFF0C\u5148\u8BFB Y \u6216\u5148\u5411\u6211\u786E\u8BA4\uFF0C\u4E0D\u8981\u81EA\u884C\u5047\u8BBE"\u3002'
2204
+ ].join("\n");
2205
+ var EVIDENCE_RULES = [
2206
+ "\u3010\u4F9D\u636E\u7EAA\u5F8B\uFF08\u5BBF\u4E3B\u4F1A\u9010\u6761\u673A\u68B0\u6838\u5BF9\uFF0C\u5199\u9519\u5C31\u4E22\u8FD9\u4E00\u6761\uFF09\u3011",
2207
+ "1. `rewrite` / `requirement` / `quality` **\u5FC5\u987B**\u5E26 `quote`\uFF1A\u4E00\u6BB5\u5728\u3010\u7528\u6237\u539F\u8BDD\u3011\u91CC",
2208
+ " **\u9010\u5B57\u5B58\u5728**\u7684\u5B50\u4E32 \u2014\u2014 \u7167\u6284\uFF0C\u4E0D\u8981\u6539\u5199\u3001\u4E0D\u8981\u8865\u6807\u70B9\u3001\u4E0D\u8981\u7FFB\u8BD1\u3002\u5BBF\u4E3B\u505A\u5B57\u9762\u5B50\u4E32\u6BD4\u5BF9\uFF0C",
2209
+ " \u5BF9\u4E0D\u4E0A\u5C31\u4E22\u6389\u90A3\u4E00\u6761\uFF08\u4E0D\u4F1A\u62A5\u9519\u7ED9\u4F60\uFF0C\u4E5F\u4E0D\u4F1A\u6709\u4EBA\u63D0\u9192\u4F60\uFF09\u3002",
2210
+ '2. **\u4E0D\u8BB8\u51ED\u7A7A\u65B0\u589E**\uFF1A\u4EA7\u54C1\u76EE\u6807\u3001\u529F\u80FD\u3001\u786C\u7EA6\u675F\uFF08"\u5FC5\u987B\u79BB\u7EBF""\u7981\u6B62\u8054\u7F51""\u53EA\u80FD\u7528\u67D0\u4E2A\u5E93"',
2211
+ ' "\u5FC5\u987B\u652F\u6301\u79FB\u52A8\u7AEF"\uFF09\u4E00\u5F8B\u4E0D\u8BB8\u7531\u4F60\u51B3\u5B9A\u3002\u4F60\u53EA\u80FD\u8865**\u80FD\u4ECE\u539F\u8BDD\u67D0\u4E00\u53E5\u76F4\u63A5\u63A8\u51FA**\u7684\u6700\u4F4E\u8981\u6C42\uFF0C',
2212
+ " \u5E76\u4E14\u5FC5\u987B\u5F15\u7528\u90A3\u4E00\u53E5\u3002",
2213
+ "3. \u4E0D\u786E\u5B9A\u3001\u4F1A\u5F71\u54CD\u7ED3\u679C\u3001\u4E14\u53EA\u6709\u7528\u6237\u80FD\u5B9A\u7684\u53D6\u820D \u2192 \u5199 `unknown`\uFF08`unknownClass` =",
2214
+ ' "user_preference"\uFF09\uFF0C**\u4E0D\u8981\u66FF\u7528\u6237\u731C**\uFF0C\u4E5F\u4E0D\u8981\u5199"\u6309\u6700\u4FDD\u5B88\u7406\u89E3\u6267\u884C"\u3002',
2215
+ ' \u5728\u8BB8\u53EF\u8303\u56F4\u5185\u8BFB\u4EE3\u7801\u5C31\u80FD\u786E\u5B9A\u7684\u4E8B\u5B9E\u5199 "lookupable_fact"\uFF1B\u53EF\u9006\u7684\u5B9E\u73B0\u7EC6\u8282',
2216
+ ' \uFF08\u95F4\u8DDD\u3001\u547D\u540D\u3001\u5E93\u7684\u5185\u90E8\u7528\u6CD5\uFF09\u5199 "implementation_detail"\u3002',
2217
+ "4. \u4E0D\u5F97\u865A\u6784\u9879\u76EE\u4E8B\u5B9E\uFF08\u6587\u4EF6\u5185\u5BB9\u3001\u76EE\u5F55\u7ED3\u6784\u3001\u4F9D\u8D56\u7248\u672C\uFF09\u3002\u4F60\u6CA1\u8BFB\u5230\u7684\u4E1C\u897F\u4E0D\u5B58\u5728\u3002"
2218
+ ].join("\n");
2219
+ var STYLE_RULES = [
2220
+ '\u3010\u5199 text \u7684\u7EAA\u5F8B\u3011\u4F60\u7684 text \u4F1A\u88AB\u5BBF\u4E3B\u62FC\u8FDB\u6700\u7EC8\u547D\u4EE4\uFF0C\u8BFB\u8005\u53EA\u6709"\u5DE5\u4F5C AI"\u4E00\u4E2A\uFF1A',
2221
+ "- \u7948\u4F7F\u53E5\u3001\u76F4\u7ED9\u8981\u6C42\u3001\u53EF\u6267\u884C\uFF1B\u4E2D\u6587\u8FDB\u4E2D\u6587\u51FA\u3002",
2222
+ '- \u4E0D\u8981\u5143\u8BDD\u8BED\u4E0E\u5143\u6807\u9898\uFF08"\u4F18\u5316\u540E\u7684\u63D0\u793A\u8BCD""\u6539\u5199\u540E""\u8BF4\u660E""\u4EE5\u4E0B\u662F\u2026"\uFF09\u3002',
2223
+ '- \u4E0D\u8981\u63D0\u5230"\u7528\u6237/\u539F\u6587/\u4E0A\u9762\u7684\u8BDD"\uFF0C\u4E5F\u4E0D\u8981\u5199"\u6211\u6765\u5E2E\u4F60\u2026"\u3002',
2224
+ '- \u4E0D\u8981\u5199\u6D41\u7A0B\u4EEA\u5F0F\u3001\u901A\u7528\u6559\u5B66\u3001\u9A8C\u6536\u5957\u8BDD\uFF08"\u8BF7\u786E\u4FDD\u4EE3\u7801\u8D28\u91CF"\u8FD9\u79CD\u6CA1\u6709\u6307\u5411\u7684\u8BDD\uFF09\u3002',
2225
+ "- `rewrite` \u7684 text \u662F**\u66FF\u6362\u6389\u90A3\u6BB5\u5F15\u6587**\u7684\u6B63\u6587\uFF0C\u6240\u4EE5\u53EA\u5199\u90A3\u6BB5\u8BDD\u672C\u8EAB\uFF0C\u4E0D\u8981\u5E26\u524D\u7F00\u540E\u7F00\u3002"
2226
+ ].join("\n");
2227
+ var OPTIMIZER_OUTPUT_CONTRACT = [
2228
+ "\u3010\u8F93\u51FA\u5951\u7EA6\uFF08\u56FA\u5B9A\uFF0C\u4E0D\u53EF\u66F4\u6539\uFF09\u3011",
2229
+ "\u53EA\u8F93\u51FA\u4E00\u4E2A JSON \u5BF9\u8C61\uFF0C\u4E0D\u8981 Markdown \u4EE3\u7801\u5757\u3001\u4E0D\u8981\u5728 JSON \u524D\u540E\u5199\u4EFB\u4F55\u5B57\uFF1A",
2230
+ '{"items":[{"kind":"rewrite","quote":"\u539F\u8BDD\u91CC\u9010\u5B57\u5B58\u5728\u7684\u7247\u6BB5","text":"\u66FF\u6362\u6389\u8BE5\u7247\u6BB5\u7684\u6B63\u6587"}]}',
2231
+ "\u5B57\u6BB5\u4E0E\u53D6\u503C\uFF08`kind` \u53EA\u80FD\u662F\u8FD9\u516D\u79CD\uFF09\uFF1A",
2232
+ "- rewrite\uFF1A\u8BED\u8A00\u5C42\u4FEE\u590D\u3002`quote` \u5FC5\u586B\uFF1B\u540C\u4E00\u6BB5\u539F\u8BDD\u6700\u591A\u4E00\u6761 rewrite\uFF0C\u4E0D\u8981\u91CD\u53E0\u3002",
2233
+ "- requirement\uFF1A\u4ECE `quote` \u76F4\u63A5\u63A8\u51FA\u7684\u8865\u5168\u8981\u6C42\uFF08\u9A8C\u6536\u6807\u51C6/\u786C\u7EA6\u675F\uFF09\u3002`quote` \u5FC5\u586B\u3002",
2234
+ "- quality\uFF1A\u5BF9\u539F\u8BDD\u91CC\u8D28\u91CF\u8BCD\u7684\u89E3\u91CA\u3002`quote` \u5FC5\u586B\uFF08\u5C31\u586B\u90A3\u51E0\u4E2A\u8D28\u91CF\u5B57\uFF09\u3002",
2235
+ "- unknown\uFF1A\u672A\u51B3\u9879\u3002\u5FC5\u987B\u5E26 `unknownClass`\uFF08user_preference / lookupable_fact /",
2236
+ " implementation_detail\uFF09\uFF0C\u53EF\u9009 `blocking`\uFF08true/false\uFF0C\u662F\u5426\u6321\u4F4F\u4E0B\u4E00\u6B65\uFF09\u3002",
2237
+ '- plan\uFF1A\u5206\u9636\u6BB5\u6267\u884C\u8BA1\u5212\uFF08\u4EC5"\u6781\u7AEF"\u6863\u7528\uFF09\u3002',
2238
+ '- risk\uFF1A\u591A\u60C5\u51B5\u9884\u6848\uFF08\u4EC5"\u6781\u7AEF"\u6863\u7528\uFF09\uFF0C\u6BCF\u6761\u6309"\u89E6\u53D1\u4FE1\u53F7 \u2192 \u5E94\u5BF9 \u2192 \u7981\u6B62\u52A8\u4F5C"\u5199\u3002',
2239
+ "\u9650\u5236\uFF1A`text` \u6BCF\u6761\u4E0D\u8D85\u8FC7 300 \u5B57\uFF1B`items` \u603B\u5171\u4E0D\u8D85\u8FC7 12 \u6761\uFF1Bid \u4E0D\u9700\u8981\u7ED9\u3002",
2240
+ '\u6CA1\u6709\u53EF\u8865\u7684\u5185\u5BB9\u65F6\uFF0C\u8F93\u51FA {"items":[]} \u2014\u2014 \u4F46**\u5148\u60F3\u6E05\u695A**\uFF1A\u7528\u6237\u8FD9\u4E00\u8F6E\u7684\u539F\u8BDD\u91CC',
2241
+ "\u771F\u7684\u6CA1\u6709\u4EFB\u4F55\u53EF\u6838\u5BF9\u7684\u8865\u5168\u5417\uFF1F"
2242
+ ].join("\n");
2243
+ var TIER_TASKS = {
2244
+ basic: [
2245
+ "\u3010\u672C\u8F6E\u4EFB\u52A1\uFF1A\u53EA\u505A\u8BED\u8A00\u5C42\u4FEE\u590D\u3011",
2246
+ "\u7528\u6237\u539F\u8BDD\u53EF\u80FD\u6709\u75C5\u53E5\u3001\u6307\u4EE3\u4E0D\u660E\u3001\u7528\u8BCD\u542B\u7CCA\u3002\u628A\u5B83\u6539\u5199\u6210\u901A\u987A\u3001\u7CBE\u786E\u3001\u65E0\u6B67\u4E49\u7684**\u540C\u4E00\u6BB5\u8BDD**\u3002",
2247
+ "\u53EA\u4EA7\u51FA `rewrite`\uFF08\u53EF\u4EE5\u6309\u53E5\u5B50\u62C6\u6210\u591A\u6761\uFF0C\u6BCF\u6761\u5F15\u7528\u539F\u8BDD\u91CC\u5BF9\u5E94\u90A3\u4E00\u53E5\uFF09\u3002",
2248
+ "\u4E25\u7981\u4EA7\u51FA requirement / plan / risk\uFF1A\u8FD9\u4E00\u6863**\u4E0D\u65B0\u589E\u4EFB\u4F55\u8981\u6C42**\uFF0C\u53EA\u628A\u8BDD\u8BF4\u660E\u767D\u3002",
2249
+ "\u539F\u8BDD\u786E\u6709\u6B67\u4E49\u3001\u4E14\u6B67\u4E49\u4F1A\u5BFC\u81F4\u505A\u9519\u65F6\uFF0C\u624D\u8865\u4E00\u6761 `unknown`\uFF08unknownClass \u53D6",
2250
+ "user_preference \u6216 lookupable_fact\uFF09\uFF1B\u786E\u5B9E\u6CA1\u6709\u53EF\u8865\u7684\u5C31\u8F93\u51FA\u7A7A\u6570\u7EC4\u3002",
2251
+ "\u957F\u5EA6\u7EAA\u5F8B\uFF1A\u6210\u54C1\u4E0D\u8D85\u8FC7\u539F\u8BDD\u7684 1.4 \u500D\uFF1B\u539F\u8BDD 30 \u5B57\u4EE5\u5185\u65F6\u4E0D\u8D85\u8FC7 60 \u5B57\u3002"
2252
+ ],
2253
+ advanced: [
2254
+ "\u3010\u672C\u8F6E\u4EFB\u52A1\uFF1A\u5728\u4E0D\u52A8\u76EE\u6807\u7684\u524D\u63D0\u4E0B\u628A\u547D\u4EE4\u8BF4\u6E05\u695A\u3011",
2255
+ '\u7528\u6237\u539F\u8BDD\u542B\u7CCA\u3001\u7F3A\u5173\u952E\u7EA6\u675F\u3002\u4F60\u8981\u8865\u7684\u662F"\u7528\u6237\u663E\u7136\u60F3\u8981\u3001\u4F46\u6CA1\u8BF4\u51FA\u53E3"\u7684\u5FC5\u8981\u4FE1\u606F\uFF0C',
2256
+ "\u8BA9\u5B83\u4E00\u6B21\u505A\u5BF9 \u2014\u2014 \u4F46\u6BCF\u4E00\u6761\u90FD\u5FC5\u987B\u662F**\u4ECE\u539F\u8BDD\u67D0\u4E00\u53E5\u76F4\u63A5\u63A8\u51FA**\u7684\uFF0C\u5E76\u5F15\u7528\u90A3\u4E00\u53E5\u3002",
2257
+ "\u5141\u8BB8\u4EA7\u51FA\uFF1A",
2258
+ "- `rewrite`\uFF1A\u628A\u542B\u7CCA\u3001\u6709\u75C5\u53E5\u7684\u5730\u65B9\u8BF4\u6E05\u695A\uFF08\u540C\u4E00\u6BB5\u539F\u8BDD\u6700\u591A\u4E00\u6761\uFF09\u3002",
2259
+ '- `requirement`\uFF1A\u4ECE\u539F\u8BDD\u76F4\u63A5\u63A8\u51FA\u7684\u6700\u4F4E\u4EA4\u4ED8\u8981\u6C42\u4E0E\u9A8C\u6536\u6807\u51C6\uFF08"\u6539\u5B8C\u80FD\u8DD1\u8D77\u6765""\u9875\u9762\u80FD\u6253\u5F00"',
2260
+ " \u8FD9\u7C7B\u53EF\u89C2\u6D4B\u7684\u8BDD\uFF09\uFF0C\u5199\u6210\u5BF9\u5DE5\u4F5C AI \u7684\u8981\u6C42\u800C\u4E0D\u662F\u8BC4\u8BBA\u3002\u6BCF\u6761\u90FD\u8981\u80FD\u6307\u56DE\u539F\u8BDD\u91CC\u7684\u67D0\u4E00\u53E5\u3002",
2261
+ '- `quality`\uFF1A\u7528\u6237\u8BF4\u7684\u8D28\u91CF\u8BCD\uFF08"\u597D\u770B\u70B9""\u9AD8\u7EA7\u611F""\u6D41\u7545"\uFF09\u2192 \u89E3\u91CA\u6210\u53EF\u89C2\u5BDF\u7684\u8981\u6C42\u3002',
2262
+ " \u5B83\u662F**\u89E3\u91CA**\uFF0C\u4E0D\u662F\u65B0\u589E\u76EE\u6807\uFF1A\u4E00\u6761\u8D28\u91CF\u8BCD\u6700\u591A\u4E00\u6761 quality\u3002",
2263
+ "- `unknown`\uFF1A\u53EA\u6709\u7528\u6237\u80FD\u5B9A\u7684\u53D6\u820D\uFF08user_preference\uFF09/ \u8BE5\u53BB\u67E5\u8BC1\u7684\u4E8B\u5B9E\uFF08lookupable_fact\uFF09\u3002",
2264
+ "\u7981\u6B62\uFF1A\u65B0\u589E\u529F\u80FD\u3001\u65B0\u76EE\u6807\u3001\u65B0\u4F9D\u8D56\uFF1B\u865A\u6784\u9879\u76EE\u4E8B\u5B9E\uFF1B\u5199\u7528\u6237\u6CA1\u6388\u6743\u7684\u6280\u672F\u9009\u578B\u3002",
2265
+ "\u6570\u91CF\u7EAA\u5F8B\uFF1Arequirement \u6700\u591A 3 \u6761\uFF0Cquality \u6700\u591A 2 \u6761\uFF0Cunknown \u6700\u591A 2 \u6761\u3002"
2266
+ ],
2267
+ extreme: [
2268
+ "\u3010\u672C\u8F6E\u4EFB\u52A1\uFF1A\u628A\u8BC9\u6C42\u56FA\u5316\u6210\u4E00\u6761\u53EF\u76F4\u63A5\u6267\u884C\u7684\u547D\u4EE4\u3011",
2269
+ "\u8FD9\u6B21\u662F\u591A\u6B65\u6267\u884C\u7684\u590D\u6742\u4EFB\u52A1\uFF0C\u5DE5\u4F5C AI \u4F1A\u7167\u8FD9\u6761\u547D\u4EE4\u5E72\uFF0C\u7528\u6237\u4E0D\u4F1A\u518D\u8865\u5145\u3002",
2270
+ '\u5728"\u9AD8\u7EA7"\u6863\u5141\u8BB8\u7684\u5168\u90E8\u6761\u76EE\u7684\u57FA\u7840\u4E0A\uFF0C\u518D\u52A0\u4E24\u7C7B\uFF08\u90FD\u8981\u4EE5\u7528\u6237\u5728\u7ED9\u5DE5\u4F5C AI \u4E0B\u547D\u4EE4\u7684\u53E3\u543B\u5199\uFF09\uFF1A',
2271
+ "- `plan`\uFF1A\u5206\u9636\u6BB5\u6267\u884C\u8BA1\u5212\u3002\u6BCF\u9636\u6BB5\u5199\u6E05\u52A8\u4F5C\u4E0E\u4EA7\u51FA\uFF0C\u5E76\u5199\u660E\u7EAA\u5F8B\uFF08\u5148\u9A8C\u8BC1\u518D\u6539\u3001\u5931\u8D25\u5373\u56DE\u9000\u3001",
2272
+ " \u4E0D\u64C5\u81EA\u6269\u5927\u8303\u56F4\u3001\u6539\u5B8C\u7ED9\u51FA\u8BC1\u636E\uFF09\u3002",
2273
+ '- `risk`\uFF1A\u591A\u60C5\u51B5\u9884\u6848 2~4 \u6761\uFF0C\u6BCF\u6761\u5199\u6210"\u5982\u679C\u51FA\u73B0 <\u89E6\u53D1\u4FE1\u53F7>\uFF0C\u5C31\u5148 <\u5E94\u5BF9\u52A8\u4F5C>\uFF0C',
2274
+ ' \u4E0D\u8981 <\u7981\u6B62\u52A8\u4F5C>"\u3002',
2275
+ "\u8FD8\u8981\u5224\u65AD\u8FD9\u6B21\u4EFB\u52A1\u662F\u5426\u503C\u5F97\u8BA9\u5DE5\u4F5C AI \u7528 goal / todo / \u8BA1\u5212\u6A21\u5F0F\u8DDF\u8E2A\uFF0C\u5E76\u628A\u7ED3\u8BBA\u5199\u6210",
2276
+ '`requirement` \u7684\u4E00\u90E8\u5206\uFF08\u4F8B\u5982"\u8BF7\u5148\u5EFA\u7ACB goal\uFF1A\u2026\uFF0C\u518D\u6309\u4E0B\u5217\u9636\u6BB5\u63A8\u8FDB"\uFF09\uFF1B\u4E0D\u9700\u8981\u5C31\u5B8C\u5168\u4E0D\u63D0\u3002',
2277
+ '\u94C1\u5F8B\uFF1A\u4E0D\u5F97\u865A\u6784\u9879\u76EE\u4E8B\u5B9E\u3002\u9700\u8981\u9879\u76EE\u4E8B\u5B9E\u65F6\u5199\u6210"\u5148\u8BFB\u53D6/\u786E\u8BA4 X"\u7684\u67E5\u8BC1\u52A8\u4F5C\u3002',
2278
+ "\u6570\u91CF\u7EAA\u5F8B\uFF1Aplan \u6700\u591A 1 \u6761\uFF0Crisk \u6700\u591A 4 \u6761\uFF0Crequirement \u6700\u591A 3 \u6761\u3002"
2279
+ ]
2280
+ };
2281
+ var OPTIMIZER_SPECS = {
2282
+ basic: {
2283
+ temperature: 0.2,
2284
+ system: [RELAY_ROLE, TIER_TASKS.basic.join("\n"), EVIDENCE_RULES, STYLE_RULES].join("\n\n")
2285
+ },
2286
+ advanced: {
2287
+ temperature: 0.3,
2288
+ system: [RELAY_ROLE, TIER_TASKS.advanced.join("\n"), EVIDENCE_RULES, STYLE_RULES].join("\n\n")
2289
+ },
2290
+ extreme: {
2291
+ temperature: 0.3,
2292
+ system: [RELAY_ROLE, TIER_TASKS.extreme.join("\n"), EVIDENCE_RULES, STYLE_RULES].join("\n\n")
2293
+ }
2294
+ };
2295
+
2296
+ // src/client/OptimizerPromptEditor.tsx
2169
2297
  var import_jsx_runtime4 = require("react/jsx-runtime");
2298
+ function builtinTaskPrompt(tier) {
2299
+ return OPTIMIZER_SPECS[tier]?.system ?? OPTIMIZER_SPECS.advanced.system;
2300
+ }
2301
+ function OptimizerPromptEditor({ tier, value, onChange }) {
2302
+ const label = OPTIMIZER_TIERS.find((item) => item.id === tier)?.label ?? tier;
2303
+ const custom = value.trim() !== "";
2304
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
2305
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: rowText, children: [
2306
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: rowTitle, children: [
2307
+ `\u672C\u6863\u63D0\u793A\u8BCD\uFF08${label}\uFF09`,
2308
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { marginLeft: 8, opacity: 0.75 }, children: custom ? "\u81EA\u5B9A\u4E49" : "\u5185\u7F6E" })
2309
+ ] }),
2310
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: rowDesc, children: [
2311
+ "\u7559\u7A7A = \u7528\u63D2\u4EF6\u5185\u7F6E\u90A3\u4EFD\u3002\u6539\u7684\u662F\u300C\u4EFB\u52A1\u4E0E\u98CE\u683C\u300D\u8FD9\u6BB5\uFF1B",
2312
+ " ",
2313
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "JSON \u8F93\u51FA\u5951\u7EA6" }),
2314
+ "\u7531\u63D2\u4EF6\u5728\u672B\u5C3E\u8FFD\u52A0\u3001\u4E0D\u5728\u8FD9\u91CC\u6539 \u2014\u2014 \u5BBF\u4E3B\u9760\u5B83\u9010\u6761\u6838\u5BF9\u300C\u6BCF\u6761\u8865\u5168\u90FD\u6307\u56DE\u4F60\u539F\u8BDD\u91CC\u7684\u67D0\u53E5\u300D\uFF0C\u5951\u7EA6\u88AB\u6539\u6389\u8FD9\u5957\u6821\u9A8C\u5C31\u6CA1\u4E86\u3002"
2315
+ ] })
2316
+ ] }),
2317
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2318
+ "textarea",
2319
+ {
2320
+ value,
2321
+ placeholder: "\u7559\u7A7A = \u7528\u5185\u7F6E\u63D0\u793A\u8BCD\u3002\u70B9\u4E0B\u9762\u7684\u300C\u8F7D\u5165\u5185\u7F6E\u7248\u300D\u53EF\u4EE5\u5148\u628A\u5185\u7F6E\u90A3\u4EFD\u6284\u8FDB\u6765\u518D\u6539\u3002",
2322
+ maxLength: OPTIMIZER_PROMPT_MAX,
2323
+ spellCheck: false,
2324
+ rows: value.trim() === "" ? 3 : Math.min(16, Math.max(6, Math.ceil(value.length / 60))),
2325
+ onChange: (event) => {
2326
+ onChange(event.target.value);
2327
+ },
2328
+ style: { ...textInput, resize: "vertical", fontFamily: "inherit", lineHeight: 1.5 }
2329
+ }
2330
+ ),
2331
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
2332
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2333
+ "button",
2334
+ {
2335
+ type: "button",
2336
+ style: pill,
2337
+ title: "\u628A\u5185\u7F6E\u90A3\u4EFD\u4EFB\u52A1\u63D0\u793A\u8BCD\u6284\u8FDB\u8F93\u5165\u6846\uFF0C\u65B9\u4FBF\u5728\u6B64\u57FA\u7840\u4E0A\u6539",
2338
+ onClick: () => {
2339
+ onChange(builtinTaskPrompt(tier));
2340
+ },
2341
+ children: "\u8F7D\u5165\u5185\u7F6E\u7248"
2342
+ }
2343
+ ),
2344
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2345
+ "button",
2346
+ {
2347
+ type: "button",
2348
+ style: pill,
2349
+ disabled: !custom,
2350
+ title: "\u6E05\u7A7A\u81EA\u5B9A\u4E49\uFF0C\u6539\u7528\u5185\u7F6E\u63D0\u793A\u8BCD",
2351
+ onClick: () => {
2352
+ onChange("");
2353
+ },
2354
+ children: "\u6062\u590D\u5185\u7F6E"
2355
+ }
2356
+ ),
2357
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { ...rowDesc, flex: "1 1 auto" }, children: `\u5F53\u524D\u5B57\u6570 ${String(value.length)} / ${String(OPTIMIZER_PROMPT_MAX)}` })
2358
+ ] }),
2359
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("details", { children: [
2360
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("summary", { style: { ...rowDesc, cursor: "pointer" }, children: "\u770B\u63D2\u4EF6\u56FA\u5B9A\u8FFD\u52A0\u7684\u90A3\u6BB5\u8F93\u51FA\u5951\u7EA6" }),
2361
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { style: { ...rowDesc, whiteSpace: "pre-wrap", margin: "6px 0 0" }, children: OPTIMIZER_OUTPUT_CONTRACT })
2362
+ ] })
2363
+ ] });
2364
+ }
2365
+
2366
+ // src/client/PillChoice.tsx
2367
+ var import_jsx_runtime5 = require("react/jsx-runtime");
2170
2368
  var base = {
2171
2369
  border: "0.5px solid var(--dsw-alias-border-l2)",
2172
2370
  background: "transparent",
@@ -2189,13 +2387,13 @@ function PillChoice({
2189
2387
  ariaLabel,
2190
2388
  compact = false
2191
2389
  }) {
2192
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2390
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2193
2391
  "div",
2194
2392
  {
2195
2393
  role: "group",
2196
2394
  "aria-label": ariaLabel,
2197
2395
  style: { display: "inline-flex", alignItems: "center", gap: 2, flex: "0 0 auto" },
2198
- children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2396
+ children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2199
2397
  "button",
2200
2398
  {
2201
2399
  type: "button",
@@ -2221,9 +2419,9 @@ function PillChoice({
2221
2419
  }
2222
2420
 
2223
2421
  // src/client/InsertModeControl.tsx
2224
- var import_jsx_runtime5 = require("react/jsx-runtime");
2422
+ var import_jsx_runtime6 = require("react/jsx-runtime");
2225
2423
  function InsertModeControl({ mode, onChange, compact = false, label }) {
2226
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2424
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2227
2425
  PillChoice,
2228
2426
  {
2229
2427
  items: INSERT_MODES,
@@ -2236,10 +2434,10 @@ function InsertModeControl({ mode, onChange, compact = false, label }) {
2236
2434
  }
2237
2435
 
2238
2436
  // src/client/SettingsSection.tsx
2239
- var import_jsx_runtime6 = require("react/jsx-runtime");
2437
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2240
2438
  var bodyLead = { ...description, margin: "12px 0" };
2241
2439
  function Chevron() {
2242
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2440
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2243
2441
  "path",
2244
2442
  {
2245
2443
  d: "M3.25 5.5L7 9.25L10.75 5.5",
@@ -2253,13 +2451,13 @@ function Chevron() {
2253
2451
  function FoldCard(props) {
2254
2452
  const [open, setOpen] = (0, import_react4.useState)(false);
2255
2453
  const off = props.toggle !== void 0 && props.toggle.checked === false;
2256
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: [
2454
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: [
2257
2455
  "dsh-ux-card",
2258
2456
  open ? "dsh-ux-cardOpen" : "",
2259
2457
  off ? "dsh-ux-cardOff" : ""
2260
2458
  ].filter((part) => part !== "").join(" "), children: [
2261
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-ux-cardHeaderRow", children: [
2262
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2459
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-ux-cardHeaderRow", children: [
2460
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2263
2461
  "button",
2264
2462
  {
2265
2463
  type: "button",
@@ -2269,17 +2467,17 @@ function FoldCard(props) {
2269
2467
  setOpen((current) => !current);
2270
2468
  },
2271
2469
  children: [
2272
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dsh-ux-cardHeadText", children: [
2273
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-ux-cardName", children: props.name }),
2274
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-ux-cardDescription", children: off ? `\u672A\u542F\u7528 \xB7 ${props.summary}` : props.summary })
2470
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-ux-cardHeadText", children: [
2471
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-ux-cardName", children: props.name }),
2472
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-ux-cardDescription", children: off ? `\u672A\u542F\u7528 \xB7 ${props.summary}` : props.summary })
2275
2473
  ] }),
2276
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: open ? "dsh-ux-cardChevron dsh-ux-cardChevronOpen" : "dsh-ux-cardChevron", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Chevron, {}) })
2474
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: open ? "dsh-ux-cardChevron dsh-ux-cardChevronOpen" : "dsh-ux-cardChevron", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Chevron, {}) })
2277
2475
  ]
2278
2476
  }
2279
2477
  ),
2280
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dsh-ux-cardControls", children: [
2478
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-ux-cardControls", children: [
2281
2479
  props.controls,
2282
- props.toggle !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2480
+ props.toggle !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2283
2481
  Switch,
2284
2482
  {
2285
2483
  small: true,
@@ -2290,7 +2488,7 @@ function FoldCard(props) {
2290
2488
  )
2291
2489
  ] })
2292
2490
  ] }),
2293
- open && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-ux-cardBody", children: props.children })
2491
+ open && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-ux-cardBody", children: props.children })
2294
2492
  ] });
2295
2493
  }
2296
2494
  function KeyRow(props) {
@@ -2335,14 +2533,14 @@ function KeyRow(props) {
2335
2533
  };
2336
2534
  }, [recording, conflict, onChange]);
2337
2535
  const base2 = first === true ? { ...row, borderTop: "none" } : row;
2338
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { ...base2, flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
2339
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowText, children: [
2340
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: title }),
2341
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowDesc, children: desc })
2536
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...base2, flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
2537
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowText, children: [
2538
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: title }),
2539
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowDesc, children: desc })
2342
2540
  ] }),
2343
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
2344
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: kbd, children: displayChord(value) }),
2345
- !recording && presets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2541
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
2542
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: kbd, children: displayChord(value) }),
2543
+ !recording && presets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2346
2544
  "button",
2347
2545
  {
2348
2546
  type: "button",
@@ -2355,11 +2553,11 @@ function KeyRow(props) {
2355
2553
  },
2356
2554
  preset
2357
2555
  )),
2358
- !recording && value !== "" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, onClick: () => {
2556
+ !recording && value !== "" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, onClick: () => {
2359
2557
  setError(null);
2360
2558
  onChange("");
2361
2559
  }, children: "\u6E05\u9664" }),
2362
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2560
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2363
2561
  "button",
2364
2562
  {
2365
2563
  type: "button",
@@ -2371,11 +2569,11 @@ function KeyRow(props) {
2371
2569
  children: recording ? "\u8BF7\u6309\u4E0B\u65B0\u7EC4\u5408\u952E\u2026" : "\u81EA\u5B9A\u4E49\u2026"
2372
2570
  }
2373
2571
  ),
2374
- recording && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, onClick: () => {
2572
+ recording && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, onClick: () => {
2375
2573
  setRecording(false);
2376
2574
  setError(null);
2377
2575
  }, children: "Esc \u53D6\u6D88" }),
2378
- error !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "var(--dsw-alias-state-error-primary)", fontSize: 12 }, children: error })
2576
+ error !== null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { color: "var(--dsw-alias-state-error-primary)", fontSize: 12 }, children: error })
2379
2577
  ] })
2380
2578
  ] });
2381
2579
  }
@@ -2384,7 +2582,7 @@ function Switch(props) {
2384
2582
  const width = small ? 30 : 36;
2385
2583
  const height = small ? 16 : 20;
2386
2584
  const knob = small ? 12 : 14;
2387
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2585
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2388
2586
  "button",
2389
2587
  {
2390
2588
  type: "button",
@@ -2406,7 +2604,7 @@ function Switch(props) {
2406
2604
  flex: "0 0 auto",
2407
2605
  padding: 0
2408
2606
  },
2409
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2607
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2410
2608
  "span",
2411
2609
  {
2412
2610
  style: {
@@ -2425,19 +2623,19 @@ function Switch(props) {
2425
2623
  );
2426
2624
  }
2427
2625
  function MiniToggle(props) {
2428
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dsh-ux-miniToggle", children: [
2429
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-ux-miniToggleLabel", children: props.label }),
2430
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Switch, { small: true, label: props.label, checked: props.checked, onChange: props.onChange })
2626
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-ux-miniToggle", children: [
2627
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-ux-miniToggleLabel", children: props.label }),
2628
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Switch, { small: true, label: props.label, checked: props.checked, onChange: props.onChange })
2431
2629
  ] });
2432
2630
  }
2433
2631
  function ToggleRow(props) {
2434
2632
  const { label, desc, checked, onChange, first } = props;
2435
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: first === true ? { ...row, borderTop: "none" } : row, children: [
2436
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowText, children: [
2437
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: label }),
2438
- desc !== void 0 && desc !== "" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowDesc, children: desc })
2633
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: first === true ? { ...row, borderTop: "none" } : row, children: [
2634
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowText, children: [
2635
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: label }),
2636
+ desc !== void 0 && desc !== "" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowDesc, children: desc })
2439
2637
  ] }),
2440
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Switch, { label, checked, onChange })
2638
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Switch, { label, checked, onChange })
2441
2639
  ] });
2442
2640
  }
2443
2641
  function TextFieldRow(props) {
@@ -2452,13 +2650,13 @@ function TextFieldRow(props) {
2452
2650
  onChange(draft.trim());
2453
2651
  };
2454
2652
  const base2 = first === true ? { ...row, borderTop: "none" } : row;
2455
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { ...base2, flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
2456
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowText, children: [
2457
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: title }),
2458
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowDesc, children: desc })
2653
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...base2, flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
2654
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowText, children: [
2655
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: title }),
2656
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowDesc, children: desc })
2459
2657
  ] }),
2460
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
2461
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2658
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
2659
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2462
2660
  "input",
2463
2661
  {
2464
2662
  type: "text",
@@ -2487,7 +2685,7 @@ function TextFieldRow(props) {
2487
2685
  style: textInput
2488
2686
  }
2489
2687
  ),
2490
- action !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, onClick: action.onClick, children: action.label })
2688
+ action !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, onClick: action.onClick, children: action.label })
2491
2689
  ] })
2492
2690
  ] });
2493
2691
  }
@@ -2521,9 +2719,9 @@ function QuickPromptsEditor(props) {
2521
2719
  border: "0.5px solid var(--dsw-alias-border-l2)",
2522
2720
  background: "var(--dsw-alias-bg-layer-1)"
2523
2721
  };
2524
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
2525
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 4, flexWrap: "wrap" }, children: [
2526
- draft.categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2722
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
2723
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 4, flexWrap: "wrap" }, children: [
2724
+ draft.categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2527
2725
  "button",
2528
2726
  {
2529
2727
  type: "button",
@@ -2540,7 +2738,7 @@ function QuickPromptsEditor(props) {
2540
2738
  },
2541
2739
  category.id
2542
2740
  )),
2543
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2741
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2544
2742
  "input",
2545
2743
  {
2546
2744
  type: "text",
@@ -2554,7 +2752,7 @@ function QuickPromptsEditor(props) {
2554
2752
  style: { ...textInput, flex: "0 0 110px" }
2555
2753
  }
2556
2754
  ),
2557
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2755
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2558
2756
  "button",
2559
2757
  {
2560
2758
  type: "button",
@@ -2568,10 +2766,10 @@ function QuickPromptsEditor(props) {
2568
2766
  }
2569
2767
  )
2570
2768
  ] }),
2571
- current === void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: rowDesc, children: "\u8FD8\u6CA1\u6709\u5206\u7C7B\u3002\u5148\u52A0\u4E00\u4E2A\u5206\u7C7B\uFF0C\u518D\u5F80\u91CC\u653E\u6761\u76EE\u3002" }),
2572
- current !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2573
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" }, children: [
2574
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2769
+ current === void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: rowDesc, children: "\u8FD8\u6CA1\u6709\u5206\u7C7B\u3002\u5148\u52A0\u4E00\u4E2A\u5206\u7C7B\uFF0C\u518D\u5F80\u91CC\u653E\u6761\u76EE\u3002" }),
2770
+ current !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2771
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" }, children: [
2772
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2575
2773
  "input",
2576
2774
  {
2577
2775
  type: "text",
@@ -2585,13 +2783,13 @@ function QuickPromptsEditor(props) {
2585
2783
  style: { ...textInput, flex: "0 0 150px" }
2586
2784
  }
2587
2785
  ),
2588
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, title: "\u5206\u7C7B\u4E0A\u79FB", onClick: () => {
2786
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, title: "\u5206\u7C7B\u4E0A\u79FB", onClick: () => {
2589
2787
  edit(withCategoryMoved(draft, current.id, -1));
2590
2788
  }, children: "\u2191" }),
2591
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, title: "\u5206\u7C7B\u4E0B\u79FB", onClick: () => {
2789
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, title: "\u5206\u7C7B\u4E0B\u79FB", onClick: () => {
2592
2790
  edit(withCategoryMoved(draft, current.id, 1));
2593
2791
  }, children: "\u2193" }),
2594
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2792
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2595
2793
  "button",
2596
2794
  {
2597
2795
  type: "button",
@@ -2603,16 +2801,16 @@ function QuickPromptsEditor(props) {
2603
2801
  children: "\u2715 \u5220\u9664\u5206\u7C7B"
2604
2802
  }
2605
2803
  ),
2606
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: rowDesc, children: [
2804
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: rowDesc, children: [
2607
2805
  current.prompts.length,
2608
2806
  " / ",
2609
2807
  QUICK_PROMPT_MAX,
2610
2808
  " \u6761"
2611
2809
  ] })
2612
2810
  ] }),
2613
- current.prompts.map((prompt) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowBox, children: [
2614
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" }, children: [
2615
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2811
+ current.prompts.map((prompt) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowBox, children: [
2812
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" }, children: [
2813
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2616
2814
  "input",
2617
2815
  {
2618
2816
  type: "text",
@@ -2626,7 +2824,7 @@ function QuickPromptsEditor(props) {
2626
2824
  style: { ...textInput, flex: "0 0 150px" }
2627
2825
  }
2628
2826
  ),
2629
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2827
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2630
2828
  InsertModeControl,
2631
2829
  {
2632
2830
  label: prompt.label,
@@ -2636,18 +2834,18 @@ function QuickPromptsEditor(props) {
2636
2834
  }
2637
2835
  }
2638
2836
  ),
2639
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { flex: 1 } }),
2640
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, title: "\u4E0A\u79FB", onClick: () => {
2837
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { flex: 1 } }),
2838
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, title: "\u4E0A\u79FB", onClick: () => {
2641
2839
  edit(withPromptMoved(draft, current.id, prompt.id, -1));
2642
2840
  }, children: "\u2191" }),
2643
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, title: "\u4E0B\u79FB", onClick: () => {
2841
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, title: "\u4E0B\u79FB", onClick: () => {
2644
2842
  edit(withPromptMoved(draft, current.id, prompt.id, 1));
2645
2843
  }, children: "\u2193" }),
2646
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, title: "\u5220\u9664\u8FD9\u6761", onClick: () => {
2844
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, title: "\u5220\u9664\u8FD9\u6761", onClick: () => {
2647
2845
  edit(withPromptRemoved(draft, current.id, prompt.id));
2648
2846
  }, children: "\u2715" })
2649
2847
  ] }),
2650
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2848
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2651
2849
  "textarea",
2652
2850
  {
2653
2851
  value: prompt.prompt,
@@ -2662,7 +2860,7 @@ function QuickPromptsEditor(props) {
2662
2860
  }
2663
2861
  )
2664
2862
  ] }, prompt.id)),
2665
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2863
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2666
2864
  AddPromptRow,
2667
2865
  {
2668
2866
  book: draft,
@@ -2676,8 +2874,8 @@ function QuickPromptsEditor(props) {
2676
2874
  }
2677
2875
  )
2678
2876
  ] }),
2679
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
2680
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2877
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
2878
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2681
2879
  "button",
2682
2880
  {
2683
2881
  type: "button",
@@ -2699,13 +2897,13 @@ function QuickPromptsEditor(props) {
2699
2897
  children: saving ? "\u4FDD\u5B58\u4E2D\u2026" : dirty ? "\u4FDD\u5B58\u4FEE\u6539" : "\u5DF2\u4FDD\u5B58"
2700
2898
  }
2701
2899
  ),
2702
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, onClick: () => {
2900
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, onClick: () => {
2703
2901
  props.onReload();
2704
2902
  }, children: "\u91CD\u65B0\u8BFB\u53D6" }),
2705
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: pill, onClick: () => {
2903
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: pill, onClick: () => {
2706
2904
  props.onReset();
2707
2905
  }, children: "\u6062\u590D\u5185\u7F6E 9 \u6761" }),
2708
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: rowDesc, children: [
2906
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: rowDesc, children: [
2709
2907
  "\u5171 ",
2710
2908
  counts.categories,
2711
2909
  " \u4E2A\u5206\u7C7B \xB7 ",
@@ -2719,9 +2917,9 @@ function QuickPromptsEditor(props) {
2719
2917
  failed ? ` \xB7 ${props.status}` : ""
2720
2918
  ] })
2721
2919
  ] }),
2722
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: rowDesc, children: [
2920
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: rowDesc, children: [
2723
2921
  "\u6570\u636E\u5B58\u5728 ",
2724
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "~/.dsh/quick-prompts.json" }),
2922
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: "~/.dsh/quick-prompts.json" }),
2725
2923
  "\uFF08\u4E0E\u4F1A\u8BDD\u3001\u9879\u76EE\u65E0\u5173\uFF0C\u53EF\u5355\u72EC\u5907\u4EFD\u6216\u624B\u5DE5\u7F16\u8F91\uFF0C \u6539\u5B8C\u70B9\u300C\u91CD\u65B0\u8BFB\u53D6\u300D\u5373\u53EF\u52A0\u8F7D\uFF09\u3002"
2726
2924
  ] })
2727
2925
  ] });
@@ -2739,7 +2937,7 @@ function DefaultTerminalBody(props) {
2739
2937
  const [busy, setBusy] = (0, import_react4.useState)(false);
2740
2938
  const candidates = settings.terminalCandidates;
2741
2939
  if (settings.terminalEffective === "unsupported") {
2742
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\u672C\u63D2\u4EF6\u53EA\u5728 Windows \u4E0A\u63A5\u7BA1\u7EC8\u7AEF\uFF08Windows \u4E0A DSH \u9ED8\u8BA4\u7ED9\u6A21\u578B\u7684\u662F PowerShell\uFF09\u3002\u5F53\u524D\u5E73\u53F0\u4E0D\u9700\u8981\u5B83\uFF0C \u8FD9\u91CC\u7684\u8BBE\u7F6E\u4E0D\u4F1A\u751F\u6548\u3002" });
2940
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\u672C\u63D2\u4EF6\u53EA\u5728 Windows \u4E0A\u63A5\u7BA1\u7EC8\u7AEF\uFF08Windows \u4E0A DSH \u9ED8\u8BA4\u7ED9\u6A21\u578B\u7684\u662F PowerShell\uFF09\u3002\u5F53\u524D\u5E73\u53F0\u4E0D\u9700\u8981\u5B83\uFF0C \u8FD9\u91CC\u7684\u8BBE\u7F6E\u4E0D\u4F1A\u751F\u6548\u3002" });
2743
2941
  }
2744
2942
  const discover = async () => {
2745
2943
  setBusy(true);
@@ -2755,13 +2953,13 @@ function DefaultTerminalBody(props) {
2755
2953
  setBusy(false);
2756
2954
  }
2757
2955
  };
2758
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2759
- !hideMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
2760
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowText, children: [
2761
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: "\u7EC8\u7AEF\u5DE5\u5177" }),
2762
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowDesc, children: TERMINAL_MODES.find((item) => item.id === settings.terminalMode)?.hint ?? "" })
2956
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2957
+ !hideMode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
2958
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowText, children: [
2959
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: "\u7EC8\u7AEF\u5DE5\u5177" }),
2960
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowDesc, children: TERMINAL_MODES.find((item) => item.id === settings.terminalMode)?.hint ?? "" })
2763
2961
  ] }),
2764
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2962
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2765
2963
  PillChoice,
2766
2964
  {
2767
2965
  items: TERMINAL_MODES,
@@ -2773,8 +2971,8 @@ function DefaultTerminalBody(props) {
2773
2971
  }
2774
2972
  )
2775
2973
  ] }),
2776
- settings.terminalMode !== "pwsh" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2777
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2974
+ settings.terminalMode !== "pwsh" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2975
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2778
2976
  TextFieldRow,
2779
2977
  {
2780
2978
  title: "Git Bash \u8DEF\u5F84",
@@ -2790,7 +2988,7 @@ function DefaultTerminalBody(props) {
2790
2988
  } }
2791
2989
  }
2792
2990
  ),
2793
- candidates.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 2 }, children: candidates.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2991
+ candidates.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 2 }, children: candidates.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2794
2992
  "button",
2795
2993
  {
2796
2994
  type: "button",
@@ -2808,15 +3006,15 @@ function DefaultTerminalBody(props) {
2808
3006
  },
2809
3007
  candidate.path
2810
3008
  )) }),
2811
- note !== "" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: note })
3009
+ note !== "" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: note })
2812
3010
  ] }),
2813
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: hintInfo, children: [
3011
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: hintInfo, children: [
2814
3012
  "\u72B6\u6001\uFF1A",
2815
3013
  settings.terminalStatus === "" ? "\u7B49\u5F85\u5BBF\u4E3B\u534A\u63A2\u6D4B\u2026" : settings.terminalStatus
2816
3014
  ] }),
2817
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\xB7 \u6362\u6210 Git Bash \u540E\uFF0C\u6A21\u578B\u770B\u5230\u7684\u7EC8\u7AEF\u5DE5\u5177\u5C31\u53EB bash\uFF08\u547D\u4EE4\u6309 bash/POSIX \u5199\uFF09\uFF0CPowerShell \u90A3\u4E2A\u5DE5\u5177 \u4F1A\u4ECE\u5B83\u7684\u5DE5\u5177\u5217\u8868\u91CC\u6D88\u5931 \u2014\u2014 \u4E00\u4E2A\u4F1A\u8BDD\u53EA\u9762\u5BF9\u4E00\u4E2A\u7EC8\u7AEF\u5DE5\u5177\u3002" }),
2818
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\xB7 \u6539\u6863\u4F4D\u4F1A\u7ACB\u523B\u91CD\u65B0\u4E0B\u53D1\u7ED9\u6B63\u5728\u8DD1\u7684\u4F1A\u8BDD\u3002\u4F46\u4F1A\u8BDD\u5386\u53F2\u91CC\u53EF\u80FD\u8FD8\u7559\u7740\u65E7\u5DE5\u5177\u540D\uFF1A\u5982\u679C\u54EA\u513F\u62A5\u4E86 unknown tool \u4E4B\u7C7B\u7684\u9519\uFF0C\u8BA9\u6A21\u578B\u6539\u7528 bash \u91CD\u8BD5\u5373\u53EF\uFF0C\u4E0D\u5F71\u54CD\u4F1A\u8BDD\u672C\u8EAB\u3002" }),
2819
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\xB7 \u53EA\u5BF9 Windows \u751F\u6548\uFF1BWSL \u7684 bash.exe \u4F1A\u88AB\u4E3B\u52A8\u6392\u9664\uFF08\u5B83\u628A D:\\ \u8FD9\u7C7B\u8DEF\u5F84\u89E3\u91CA\u6210 /mnt/d\uFF0C\u4E0E\u6A21\u578B\u624B\u91CC\u7684 Windows \u5DE5\u4F5C\u76EE\u5F55\u4E0D\u517C\u5BB9\uFF09\u3002\u6C99\u7BB1\u3001\u5BA1\u6279\u3001\u8D85\u65F6\u4E0E\u8F93\u51FA\u622A\u65AD\u7684\u884C\u4E3A\u4E0E DSH \u81EA\u5E26\u7EC8\u7AEF\u4E00\u81F4\u3002" })
3015
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\xB7 \u6362\u6210 Git Bash \u540E\uFF0C\u6A21\u578B\u770B\u5230\u7684\u7EC8\u7AEF\u5DE5\u5177\u5C31\u53EB bash\uFF08\u547D\u4EE4\u6309 bash/POSIX \u5199\uFF09\uFF0CPowerShell \u90A3\u4E2A\u5DE5\u5177 \u4F1A\u4ECE\u5B83\u7684\u5DE5\u5177\u5217\u8868\u91CC\u6D88\u5931 \u2014\u2014 \u4E00\u4E2A\u4F1A\u8BDD\u53EA\u9762\u5BF9\u4E00\u4E2A\u7EC8\u7AEF\u5DE5\u5177\u3002" }),
3016
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\xB7 \u6539\u6863\u4F4D\u4F1A\u7ACB\u523B\u91CD\u65B0\u4E0B\u53D1\u7ED9\u6B63\u5728\u8DD1\u7684\u4F1A\u8BDD\u3002\u4F46\u4F1A\u8BDD\u5386\u53F2\u91CC\u53EF\u80FD\u8FD8\u7559\u7740\u65E7\u5DE5\u5177\u540D\uFF1A\u5982\u679C\u54EA\u513F\u62A5\u4E86 unknown tool \u4E4B\u7C7B\u7684\u9519\uFF0C\u8BA9\u6A21\u578B\u6539\u7528 bash \u91CD\u8BD5\u5373\u53EF\uFF0C\u4E0D\u5F71\u54CD\u4F1A\u8BDD\u672C\u8EAB\u3002" }),
3017
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\xB7 \u53EA\u5BF9 Windows \u751F\u6548\uFF1BWSL \u7684 bash.exe \u4F1A\u88AB\u4E3B\u52A8\u6392\u9664\uFF08\u5B83\u628A D:\\ \u8FD9\u7C7B\u8DEF\u5F84\u89E3\u91CA\u6210 /mnt/d\uFF0C\u4E0E\u6A21\u578B\u624B\u91CC\u7684 Windows \u5DE5\u4F5C\u76EE\u5F55\u4E0D\u517C\u5BB9\uFF09\u3002\u6C99\u7BB1\u3001\u5BA1\u6279\u3001\u8D85\u65F6\u4E0E\u8F93\u51FA\u622A\u65AD\u7684\u884C\u4E3A\u4E0E DSH \u81EA\u5E26\u7EC8\u7AEF\u4E00\u81F4\u3002" })
2820
3018
  ] });
2821
3019
  }
2822
3020
  var RESTART_WAIT_MS = 6e4;
@@ -2930,7 +3128,7 @@ function useRestart() {
2930
3128
  function RestartButton({ restart }) {
2931
3129
  const busy = restart.stage === "restarting" || restart.stage === "asking";
2932
3130
  const blocked = restart.blocked;
2933
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3131
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2934
3132
  "button",
2935
3133
  {
2936
3134
  type: "button",
@@ -2944,28 +3142,44 @@ function RestartButton({ restart }) {
2944
3142
  }
2945
3143
  );
2946
3144
  }
3145
+ function RefreshButton({ busy }) {
3146
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3147
+ "button",
3148
+ {
3149
+ type: "button",
3150
+ className: "dsh-ux-restartButton",
3151
+ disabled: busy,
3152
+ title: "\u5237\u65B0\u9875\u9762\uFF1A\u8BA9\u63D2\u4EF6\u5BA2\u6237\u7AEF\u534A\u7684\u65B0\u4EE3\u7801\uFF08\u8BBE\u7F6E\u9875 / \u53F3\u952E\u83DC\u5355 / \u952E\u4F4D / \u5FEB\u6377\u6307\u4EE4\u9762\u677F\uFF09\u751F\u6548\u3002\u4E0D\u91CD\u542F DSH\u3001\u4E0D\u6253\u65AD\u6B63\u5728\u8DD1\u7684\u4F1A\u8BDD\u3002",
3153
+ onClick: () => {
3154
+ window.location.reload();
3155
+ },
3156
+ children: "\u5237\u65B0"
3157
+ }
3158
+ );
3159
+ }
2947
3160
  function RestartBanner({ restart }) {
2948
3161
  if (restart.stage === "idle") return null;
2949
3162
  const failed = restart.stage === "failed";
2950
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: failed ? "dsh-ux-restartBanner dsh-ux-restartBannerFailed" : "dsh-ux-restartBanner", children: [
2951
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-ux-restartBannerText", children: restart.detail }),
2952
- restart.stage === "asking" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dsh-ux-restartBannerActions", children: [
2953
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "dsh-ux-restartGo", onClick: () => {
3163
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: failed ? "dsh-ux-restartBanner dsh-ux-restartBannerFailed" : "dsh-ux-restartBanner", children: [
3164
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-ux-restartBannerText", children: restart.detail }),
3165
+ restart.stage === "asking" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-ux-restartBannerActions", children: [
3166
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-ux-restartGo", onClick: () => {
2954
3167
  restart.confirm();
2955
3168
  }, children: "\u786E\u8BA4\u91CD\u542F" }),
2956
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "dsh-ux-restartCancel", onClick: () => {
3169
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-ux-restartCancel", onClick: () => {
2957
3170
  restart.cancel();
2958
3171
  }, children: "\u53D6\u6D88" })
2959
3172
  ] }),
2960
- failed && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-ux-restartBannerActions", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "dsh-ux-restartCancel", onClick: () => {
3173
+ failed && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-ux-restartBannerActions", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-ux-restartCancel", onClick: () => {
2961
3174
  restart.cancel();
2962
3175
  }, children: "\u77E5\u9053\u4E86" }) })
2963
3176
  ] });
2964
3177
  }
2965
- function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3178
+ function SettingsSection({ useLive, useBook, useBookStatus, useWriteNotice, actions }) {
2966
3179
  const settings = useLive((item) => item);
2967
3180
  const book = useBook((item) => item);
2968
3181
  const bookStatus = useBookStatus((item) => item);
3182
+ const writeNotice = useWriteNotice((item) => item);
2969
3183
  const [conflict, setConflict] = (0, import_react4.useState)(null);
2970
3184
  const restart = useRestart();
2971
3185
  const sections = activeSections(settings);
@@ -2982,22 +3196,23 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
2982
3196
  const menuEnabled = MENU_ITEMS.filter((item) => settings[item.field]).length;
2983
3197
  const keySummary = `\u53D1\u9001 ${displayChord(settings.sendKey)} \xB7 \u6362\u884C ${displayChord(settings.newlineKey)}`;
2984
3198
  const menuSummary = settings.menuMode === "official" ? "\u5F53\u524D\uFF1A\u5B98\u65B9\u4E0D\u4ECB\u5165" : settings.menuMode === "browser" ? "\u5F53\u524D\uFF1A\u6D4F\u89C8\u5668\u83DC\u5355\uFF08\u7C98\u8D34\u514D\u6388\u6743\uFF09" : `\u5F53\u524D\uFF1A\u81EA\u5B9A\u4E49\u83DC\u5355 \xB7 ${menuEnabled} / ${MENU_ITEMS.length} \u9879\u5F00\u542F`;
2985
- const panelSummary = `\u5BFC\u822A\u6EDA\u52A8 ${settings.panelScroll ? "\u5F00" : "\u5173"} \xB7 \u8FB9\u7F18\u7F29\u653E ${settings.panelResize ? "\u5F00" : "\u5173"} \xB7 ${settings.panelWidth}\xD7${settings.panelHeight}`;
3199
+ const panelSummary = `\u8FB9\u7F18\u7F29\u653E ${settings.panelResize ? "\u5F00" : "\u5173"} \xB7 ${settings.panelWidth}\xD7${settings.panelHeight}`;
2986
3200
  const headerSummary = settings.headerEnabled ? settings.headerStatus === "" ? "\u5DF2\u542F\u7528" : settings.headerStatus : "\u672A\u542F\u7528";
2987
3201
  const quickCounts = bookCounts(book);
2988
3202
  const quickSummary = `${quickCounts.categories} \u4E2A\u5206\u7C7B \xB7 ${quickCounts.prompts} \u6761 \xB7 \u6BCF\u6B21 ${quickCounts.always} \xB7 \u4EC5\u9996\u6B21 ${quickCounts.first} \xB7 \u4F18\u5316\u6863\u4F4D ${OPTIMIZER_TIERS.find((item) => item.id === settings.optimizerTier)?.label ?? "\u9AD8\u7EA7"}`;
2989
3203
  const headerStatusText = settings.headerEnabled ? settings.headerStatus === "" ? "\u7B49\u5F85\u9996\u6B21\u5199\u5165\u2026" : settings.headerStatus : "\u672A\u542F\u7528\uFF08\u6253\u5F00\u4E0A\u65B9\u5F00\u5173\u5373\u5199\u5165\uFF09";
2990
3204
  const terminalSummary = sections.terminal === false ? settings.terminalMode === "pwsh" ? "\u4FDD\u6301 PowerShell" : "\u6253\u5F00\u540E\u63A5\u7BA1\u7EC8\u7AEF" : settings.terminalEffective === "unsupported" ? "\u975E Windows\uFF1A\u4E0D\u9700\u8981" : settings.terminalMode === "pwsh" ? "\u5F53\u524D\uFF1A\u4FDD\u6301 PowerShell" : settings.terminalEffective === "bash" ? "\u5F53\u524D\uFF1AGit Bash" : "\u5F53\u524D\uFF1APowerShell\uFF08\u672A\u63A5\u7BA1\uFF09";
2991
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { padding: "4px 2px" }, children: [
2992
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "dsh-ux-card", children: [
2993
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-ux-cardHeaderStatic", children: [
2994
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dsh-ux-cardHeadText", children: [
2995
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { className: "dsh-ux-cardName", children: "\u8F93\u5165\u4F53\u9A8C" }),
2996
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dsh-ux-cardDescription", children: "dsh-composer-ux \xB7 \u4E3B\u804A\u5929\u8F93\u5165\u6846\u7684\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\uFF1B\u8BBE\u7F6E\u5373\u65F6\u751F\u6548\u5E76\u6301\u4E45\u4FDD\u5B58\u3002" })
3205
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: "4px 2px" }, children: [
3206
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "dsh-ux-card", children: [
3207
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-ux-cardHeaderStatic", children: [
3208
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-ux-cardHeadText", children: [
3209
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { className: "dsh-ux-cardName", children: "\u8F93\u5165\u4F53\u9A8C" }),
3210
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "dsh-ux-cardDescription", children: "dsh-composer-ux \xB7 \u4E3B\u804A\u5929\u8F93\u5165\u6846\u7684\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\uFF1B\u8BBE\u7F6E\u5373\u65F6\u751F\u6548\u5E76\u6301\u4E45\u4FDD\u5B58\u3002" })
2997
3211
  ] }),
2998
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dsh-ux-cardActions", children: [
2999
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestartButton, { restart }),
3000
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3212
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-ux-cardActions", children: [
3213
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshButton, { busy: restart.stage === "restarting" || restart.stage === "asking" }),
3214
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RestartButton, { restart }),
3215
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3001
3216
  "a",
3002
3217
  {
3003
3218
  className: "dsh-ux-cardLink",
@@ -3007,15 +3222,24 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3007
3222
  title: "\u5728 GitHub \u4E0A\u67E5\u770B\u8FD9\u4E2A\u63D2\u4EF6\uFF08\u65B0\u6807\u7B7E\u6253\u5F00\uFF09",
3008
3223
  children: [
3009
3224
  "GitHub ",
3010
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": "true", children: "\u2197" })
3225
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\u2197" })
3011
3226
  ]
3012
3227
  }
3013
3228
  )
3014
3229
  ] })
3015
3230
  ] }),
3016
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestartBanner, { restart }),
3017
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-ux-cardBody", children: [
3018
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3231
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RestartBanner, { restart }),
3232
+ writeNotice !== "" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-ux-restartBanner dsh-ux-restartBannerFailed", role: "status", children: [
3233
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-ux-restartBannerText", children: [
3234
+ "\u8BBE\u7F6E\u672A\u751F\u6548\uFF1A",
3235
+ writeNotice
3236
+ ] }),
3237
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-ux-restartBannerActions", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-ux-restartCancel", onClick: () => {
3238
+ actions.dismissNotice();
3239
+ }, children: "\u77E5\u9053\u4E86" }) })
3240
+ ] }),
3241
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-ux-cardBody", children: [
3242
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3019
3243
  ToggleRow,
3020
3244
  {
3021
3245
  first: true,
@@ -3027,11 +3251,11 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3027
3251
  }
3028
3252
  }
3029
3253
  ),
3030
- !settings.enabled && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\u5DF2\u505C\u7528\uFF1A\u53D1\u9001/\u6362\u884C\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u3001\u8BBE\u7F6E\u9762\u677F\u6EDA\u52A8\u4E0E\u8FB9\u7F18\u7F29\u653E\u5747\u4E0D\u518D\u751F\u6548\uFF0C\u8F93\u5165\u6846\u6062\u590D DSH \u539F\u751F\u884C\u4E3A\u3002 \u6253\u5F00\u4E0A\u65B9\u5F00\u5173\u5373\u53EF\u4E00\u952E\u6062\u590D\uFF1B\u6240\u6709\u8BBE\u7F6E\u503C\u4ECD\u4FDD\u7559\u3002" })
3254
+ !settings.enabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\u5DF2\u505C\u7528\uFF1A\u53D1\u9001/\u6362\u884C\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u3001\u8BBE\u7F6E\u9762\u677F\u6EDA\u52A8\u4E0E\u8FB9\u7F18\u7F29\u653E\u5747\u4E0D\u518D\u751F\u6548\uFF0C\u8F93\u5165\u6846\u6062\u590D DSH \u539F\u751F\u884C\u4E3A\u3002 \u6253\u5F00\u4E0A\u65B9\u5F00\u5173\u5373\u53EF\u4E00\u952E\u6062\u590D\uFF1B\u6240\u6709\u8BBE\u7F6E\u503C\u4ECD\u4FDD\u7559\u3002" })
3031
3255
  ] })
3032
3256
  ] }),
3033
- settings.enabled && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3034
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3257
+ settings.enabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
3258
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3035
3259
  FoldCard,
3036
3260
  {
3037
3261
  name: "\u952E\u4F4D",
@@ -3043,8 +3267,8 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3043
3267
  }
3044
3268
  },
3045
3269
  children: [
3046
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: bodyLead, children: "\u652F\u6301\u5E38\u7528\u9884\u8BBE\uFF0C\u4E5F\u53EF\u4EE5\u70B9\u51FB\u300C\u81EA\u5B9A\u4E49\u2026\u300D\u540E\u76F4\u63A5\u6309\u4E0B\u4EFB\u610F\u7EC4\u5408\u952E\u5F55\u5236\uFF08Esc \u53D6\u6D88\uFF0CBackspace \u6E05\u9664\uFF09\u3002 \u672A\u7ED1\u5B9A\u7684 Enter \u7CFB\u6309\u952E\u4E0D\u4F1A\u89E6\u53D1\u53D1\u9001\u6216\u6362\u884C\uFF1BCtrl+Enter / \u2318+Enter \u672A\u88AB\u7ED1\u5B9A\u65F6\u4FDD\u7559\u539F\u300C\u52A0\u901F\u63D0\u4EA4\u300D\u884C\u4E3A\uFF1B \u4E2D\u6587\u8F93\u5165\u6CD5\u7EC4\u5408\u671F\u95F4\u4E0D\u53D7\u5F71\u54CD\u3002" }),
3047
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3270
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: bodyLead, children: "\u652F\u6301\u5E38\u7528\u9884\u8BBE\uFF0C\u4E5F\u53EF\u4EE5\u70B9\u51FB\u300C\u81EA\u5B9A\u4E49\u2026\u300D\u540E\u76F4\u63A5\u6309\u4E0B\u4EFB\u610F\u7EC4\u5408\u952E\u5F55\u5236\uFF08Esc \u53D6\u6D88\uFF0CBackspace \u6E05\u9664\uFF09\u3002 \u672A\u7ED1\u5B9A\u7684 Enter \u7CFB\u6309\u952E\u4E0D\u4F1A\u89E6\u53D1\u53D1\u9001\u6216\u6362\u884C\uFF1BCtrl+Enter / \u2318+Enter \u672A\u88AB\u7ED1\u5B9A\u65F6\u4FDD\u7559\u539F\u300C\u52A0\u901F\u63D0\u4EA4\u300D\u884C\u4E3A\uFF1B \u4E2D\u6587\u8F93\u5165\u6CD5\u7EC4\u5408\u671F\u95F4\u4E0D\u53D7\u5F71\u54CD\u3002" }),
3271
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3048
3272
  KeyRow,
3049
3273
  {
3050
3274
  first: true,
@@ -3058,7 +3282,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3058
3282
  }
3059
3283
  }
3060
3284
  ),
3061
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3285
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3062
3286
  KeyRow,
3063
3287
  {
3064
3288
  title: "\u6362\u884C\u952E",
@@ -3071,8 +3295,8 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3071
3295
  }
3072
3296
  }
3073
3297
  ),
3074
- conflictHint !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintError, children: conflictHint }),
3075
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { marginTop: 10 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3298
+ conflictHint !== null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintError, children: conflictHint }),
3299
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { marginTop: 10 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3076
3300
  "button",
3077
3301
  {
3078
3302
  type: "button",
@@ -3087,7 +3311,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3087
3311
  ]
3088
3312
  }
3089
3313
  ),
3090
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3314
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3091
3315
  FoldCard,
3092
3316
  {
3093
3317
  name: "\u53F3\u952E\u83DC\u5355",
@@ -3099,10 +3323,10 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3099
3323
  }
3100
3324
  },
3101
3325
  children: [
3102
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: bodyLead, children: "\u53F3\u952E\u70B9\u51FB\u8F93\u5165\u6846\u65F6\u5F39\u51FA\u54EA\u4E00\u79CD\u83DC\u5355\u3002\u53EA\u5F71\u54CD\u53F3\u952E\uFF0C\u4E0D\u5F71\u54CD\u952E\u4F4D\u4E0E\u5176\u5B83\u529F\u80FD\u3002" }),
3103
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
3104
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowText, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: "\u83DC\u5355\u6765\u6E90" }) }),
3105
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3326
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: bodyLead, children: "\u53F3\u952E\u70B9\u51FB\u8F93\u5165\u6846\u65F6\u5F39\u51FA\u54EA\u4E00\u79CD\u83DC\u5355\u3002\u53EA\u5F71\u54CD\u53F3\u952E\uFF0C\u4E0D\u5F71\u54CD\u952E\u4F4D\u4E0E\u5176\u5B83\u529F\u80FD\u3002" }),
3327
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
3328
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowText, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: "\u83DC\u5355\u6765\u6E90" }) }),
3329
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3106
3330
  PillChoice,
3107
3331
  {
3108
3332
  items: MENU_MODES,
@@ -3114,27 +3338,27 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3114
3338
  }
3115
3339
  )
3116
3340
  ] }),
3117
- settings.menuMode === "official" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: hintInfo, children: [
3118
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u5B98\u65B9" }),
3341
+ settings.menuMode === "official" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: hintInfo, children: [
3342
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "\u5B98\u65B9" }),
3119
3343
  "\uFF1A\u672C\u63D2\u4EF6\u5B8C\u5168\u4E0D\u4ECB\u5165\uFF0CDSH \u4E0E\u5176\u5B83\u63D2\u4EF6\u81EA\u5DF1\u7684\u53F3\u952E\u5904\u7406\u539F\u6837\u751F\u6548 \uFF08DSH \u5B98\u65B9\u8F93\u5165\u6846\u672C\u8EAB\u6CA1\u6709\u53F3\u952E\u83DC\u5355\uFF0C\u6240\u4EE5\u901A\u5E38\u770B\u5230\u7684\u5C31\u662F\u6D4F\u89C8\u5668\u7684\u83DC\u5355\uFF09\u3002"
3120
3344
  ] }),
3121
- settings.menuMode === "browser" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: hintInfo, children: [
3122
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u6D4F\u89C8\u5668" }),
3345
+ settings.menuMode === "browser" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: hintInfo, children: [
3346
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "\u6D4F\u89C8\u5668" }),
3123
3347
  "\uFF1A\u56FA\u5B9A\u7528\u6D4F\u89C8\u5668\u81EA\u5E26\u7684\u83DC\u5355\uFF08\u6837\u5B50\u968F\u6D4F\u89C8\u5668\u800C\u53D8\uFF09\uFF0C\u5E76\u5728\u672C\u63D2\u4EF6\u8FD9\u4E00\u5C42 \u6321\u4F4F\u5176\u5B83\u63D2\u4EF6\u7684\u83DC\u5355\uFF1B\u597D\u5904\u662F\u7C98\u8D34\u514D\u6388\u6743\u3001\u96F6\u914D\u7F6E\u3002"
3124
3348
  ] }),
3125
- settings.menuMode === "custom" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3126
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: hintInfo, children: [
3127
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u81EA\u5B9A\u4E49" }),
3349
+ settings.menuMode === "custom" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
3350
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: hintInfo, children: [
3351
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "\u81EA\u5B9A\u4E49" }),
3128
3352
  "\uFF1A\u7528\u672C\u63D2\u4EF6\u56FA\u5B9A\u6837\u5F0F\u7684\u83DC\u5355\uFF08\u672A\u9009\u4E2D\u6587\u672C\u65F6\u300C\u526A\u5207 / \u590D\u5236 / \u5220\u9664\u300D\u7F6E\u7070\uFF09\u3002 \u8FD9\u4E00\u6863\u7684\u300C\u7C98\u8D34\u300D\u8981\u8BFB\u526A\u8D34\u677F\uFF0C\u6D4F\u89C8\u5668\u4F1A\u5148\u8981\u4E00\u6B21\u6388\u6743\u2014\u2014\u4E09\u5BB6\u6D4F\u89C8\u5668\u7684\u5904\u7406\u4E0D\u4E00\u6837\uFF1A"
3129
3353
  ] }),
3130
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\xB7 Chrome / Edge\uFF08\u8C37\u6B4C / \u5FAE\u8F6F\u6D4F\u89C8\u5668\uFF09\uFF1A\u5F39\u51FA\u540E\u70B9\u300C\u5141\u8BB8\u300D\u5373\u53EF\uFF0C\u4E4B\u540E\u4F1A\u8BB0\u4F4F\u8FD9\u4E2A\u7AD9\u70B9\u3001\u4E0D\u518D\u95EE\u3002 \u8981\u6539\u6216\u64A4\u9500\u6388\u6743\uFF1A\u70B9\u5730\u5740\u680F\u6700\u5DE6\u8FB9\u7684\u7F51\u7AD9\u56FE\u6807 \u2192 \u7F51\u7AD9\u8BBE\u7F6E\uFF08Edge \u53EB\u300C\u6B64\u7AD9\u70B9\u7684\u6743\u9650\u300D\uFF09\u2192 \u526A\u8D34\u677F\uFF1B \u4E5F\u53EF\u4EE5\u76F4\u63A5\u5728\u5730\u5740\u680F\u8F93\u5165 chrome://settings/content/clipboard\uFF08Edge \u8F93\u5165 edge://settings/content/clipboard\uFF09\u3002" }),
3131
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\xB7 Firefox\uFF1A\u4E0D\u5141\u8BB8\u7F51\u9875\u9759\u9ED8\u8BFB\u526A\u8D34\u677F\u2014\u2014\u4F60\u70B9\u672C\u63D2\u4EF6\u7684\u300C\u7C98\u8D34\u300D\u540E\uFF0C\u5B83\u4F1A\u5148\u5F39\u4E00\u4E2A\u53EA\u6709\u300C\u7C98\u8D34(P)\u300D \u4E00\u9879\u7684\u5C0F\u7A97\uFF08\u7EA6 1 \u79D2\u540E\u624D\u53EF\u70B9\uFF09\uFF0C\u70B9\u5B83\u624D\u5B8C\u6210\u8FD9\u6B21\u7C98\u8D34\u3002\u8FD9\u662F Firefox \u7684\u5B89\u5168\u673A\u5236\uFF0C\u63D2\u4EF6\u5173\u4E0D\u6389 \uFF08\u5B9E\u6D4B\uFF1Aabout:config \u91CC\u7684\u526A\u8D34\u677F\u9996\u9009\u9879\u5BF9\u5B83\u65E0\u6548\uFF09\u3002\u4E0D\u60F3\u591A\u8FD9\u4E00\u6B65\u5C31\u76F4\u63A5\u6309 Ctrl+V\uFF0C \u6216\u628A\u4E0A\u9762\u7684\u300C\u83DC\u5355\u6765\u6E90\u300D\u6362\u6210\u300C\u6D4F\u89C8\u5668 / \u5B98\u65B9\u300D\u6863\u2014\u2014\u90A3\u4E24\u6863\u7528\u7684\u662F\u6D4F\u89C8\u5668\u81EA\u5DF1\u7684\u7C98\u8D34\u3002" }),
3132
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintInfo, children: "\u6CE8\u610F\uFF1Achrome://\u3001edge:// \u8FD9\u4E9B\u5730\u5740\u6D4F\u89C8\u5668\u4E0D\u5141\u8BB8\u505A\u6210\u7F51\u9875\u91CC\u7684\u94FE\u63A5\uFF0C\u53EA\u80FD\u624B\u8F93\uFF0C \u6216\u590D\u5236\u4E0A\u9762\u90A3\u4E32\u7C98\u8D34\u5230\u5730\u5740\u680F\u3002" }),
3133
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { ...row, flexDirection: "column", alignItems: "stretch", gap: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowText, children: [
3134
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: "\u83DC\u5355\u6761\u76EE" }),
3135
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowDesc, children: "\u8FD9 7 \u4E2A\u5F00\u5173\u51B3\u5B9A\u81EA\u5B9A\u4E49\u83DC\u5355\u91CC\u51FA\u73B0\u54EA\u4E9B\u6761\u76EE\uFF0C\u5173\u6389\u7684\u4E0D\u663E\u793A\u3002" })
3354
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\xB7 Chrome / Edge\uFF08\u8C37\u6B4C / \u5FAE\u8F6F\u6D4F\u89C8\u5668\uFF09\uFF1A\u5F39\u51FA\u540E\u70B9\u300C\u5141\u8BB8\u300D\u5373\u53EF\uFF0C\u4E4B\u540E\u4F1A\u8BB0\u4F4F\u8FD9\u4E2A\u7AD9\u70B9\u3001\u4E0D\u518D\u95EE\u3002 \u8981\u6539\u6216\u64A4\u9500\u6388\u6743\uFF1A\u70B9\u5730\u5740\u680F\u6700\u5DE6\u8FB9\u7684\u7F51\u7AD9\u56FE\u6807 \u2192 \u7F51\u7AD9\u8BBE\u7F6E\uFF08Edge \u53EB\u300C\u6B64\u7AD9\u70B9\u7684\u6743\u9650\u300D\uFF09\u2192 \u526A\u8D34\u677F\uFF1B \u4E5F\u53EF\u4EE5\u76F4\u63A5\u5728\u5730\u5740\u680F\u8F93\u5165 chrome://settings/content/clipboard\uFF08Edge \u8F93\u5165 edge://settings/content/clipboard\uFF09\u3002" }),
3355
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\xB7 Firefox\uFF1A\u4E0D\u5141\u8BB8\u7F51\u9875\u9759\u9ED8\u8BFB\u526A\u8D34\u677F\u2014\u2014\u4F60\u70B9\u672C\u63D2\u4EF6\u7684\u300C\u7C98\u8D34\u300D\u540E\uFF0C\u5B83\u4F1A\u5148\u5F39\u4E00\u4E2A\u53EA\u6709\u300C\u7C98\u8D34(P)\u300D \u4E00\u9879\u7684\u5C0F\u7A97\uFF08\u7EA6 1 \u79D2\u540E\u624D\u53EF\u70B9\uFF09\uFF0C\u70B9\u5B83\u624D\u5B8C\u6210\u8FD9\u6B21\u7C98\u8D34\u3002\u8FD9\u662F Firefox \u7684\u5B89\u5168\u673A\u5236\uFF0C\u63D2\u4EF6\u5173\u4E0D\u6389 \uFF08\u5B9E\u6D4B\uFF1Aabout:config \u91CC\u7684\u526A\u8D34\u677F\u9996\u9009\u9879\u5BF9\u5B83\u65E0\u6548\uFF09\u3002\u4E0D\u60F3\u591A\u8FD9\u4E00\u6B65\u5C31\u76F4\u63A5\u6309 Ctrl+V\uFF0C \u6216\u628A\u4E0A\u9762\u7684\u300C\u83DC\u5355\u6765\u6E90\u300D\u6362\u6210\u300C\u6D4F\u89C8\u5668 / \u5B98\u65B9\u300D\u6863\u2014\u2014\u90A3\u4E24\u6863\u7528\u7684\u662F\u6D4F\u89C8\u5668\u81EA\u5DF1\u7684\u7C98\u8D34\u3002" }),
3356
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintInfo, children: "\u6CE8\u610F\uFF1Achrome://\u3001edge:// \u8FD9\u4E9B\u5730\u5740\u6D4F\u89C8\u5668\u4E0D\u5141\u8BB8\u505A\u6210\u7F51\u9875\u91CC\u7684\u94FE\u63A5\uFF0C\u53EA\u80FD\u624B\u8F93\uFF0C \u6216\u590D\u5236\u4E0A\u9762\u90A3\u4E32\u7C98\u8D34\u5230\u5730\u5740\u680F\u3002" }),
3357
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { ...row, flexDirection: "column", alignItems: "stretch", gap: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowText, children: [
3358
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: "\u83DC\u5355\u6761\u76EE" }),
3359
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowDesc, children: "\u8FD9 7 \u4E2A\u5F00\u5173\u51B3\u5B9A\u81EA\u5B9A\u4E49\u83DC\u5355\u91CC\u51FA\u73B0\u54EA\u4E9B\u6761\u76EE\uFF0C\u5173\u6389\u7684\u4E0D\u663E\u793A\u3002" })
3136
3360
  ] }) }),
3137
- MENU_ITEMS.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3361
+ MENU_ITEMS.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3138
3362
  ToggleRow,
3139
3363
  {
3140
3364
  first: index === 0,
@@ -3147,7 +3371,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3147
3371
  },
3148
3372
  item.field
3149
3373
  )),
3150
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { padding: "8px 0 2px" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3374
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { padding: "8px 0 2px" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3151
3375
  "button",
3152
3376
  {
3153
3377
  type: "button",
@@ -3162,7 +3386,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3162
3386
  ]
3163
3387
  }
3164
3388
  ),
3165
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3389
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3166
3390
  FoldCard,
3167
3391
  {
3168
3392
  name: "\u5FEB\u6377\u6307\u4EE4",
@@ -3174,21 +3398,23 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3174
3398
  }
3175
3399
  },
3176
3400
  children: [
3177
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: bodyLead, children: [
3401
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: bodyLead, children: [
3178
3402
  "\u8F93\u5165\u6846\u5DE5\u5177\u884C\u91CC\u90A3\u4E2A\u300C\u5FEB\u6377\u6307\u4EE4\u300D\u6309\u94AE\u70B9\u5F00\u5C31\u662F\u8FD9\u5F20\u6E05\u5355\uFF1A\u70B9\u6761\u76EE\u628A\u5185\u5BB9\u63D2\u5165\u8F93\u5165\u6846\u3002 \u6BCF\u6761\u53F3\u4FA7\u7684\u4E09\u9009\u4E00\u51B3\u5B9A",
3179
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u53D1\u9001\u65F6\u600E\u4E48\u9644\u52A0" }),
3403
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "\u53D1\u9001\u65F6\u600E\u4E48\u9644\u52A0" }),
3180
3404
  "\uFF1A \u300C\u5173\u300D= \u53EA\u63D2\u5165\u4E0D\u9644\u52A0\uFF1B\u300C\u6BCF\u6B21\u300D= \u6BCF\u6B21\u53D1\u9001\u90FD\u9644\u52A0\u5230\u6D88\u606F",
3181
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u672B\u5C3E" }),
3405
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "\u672B\u5C3E" }),
3182
3406
  "\uFF1B \u300C\u4EC5\u9996\u6B21\u300D= \u53EA\u5728",
3183
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u8FD9\u4E2A\u4F1A\u8BDD\u7684\u7B2C\u4E00\u6761\u6D88\u606F" }),
3184
- "\u4E0A\u9644\u52A0\uFF08\u4E4B\u540E\u4E0D\u518D\u9644\u52A0\uFF0C\u5237\u65B0\u9875\u9762\u4E5F\u4E0D\u4F1A\u91CD\u590D\uFF09\u3002 \u591A\u6761\u6309\u5217\u8868\u987A\u5E8F\u62FC\u63A5\uFF0C\u8F93\u5165\u6846\u91CC\u4E0D\u63D0\u524D\u663E\u793A\u3002 \u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\u4F1A\u7528\u53E6\u4E00\u4E2A AI \u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u6574\u7406\u6210\u4E00\u6761\u80FD\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C \u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846\uFF08Ctrl+Z \u53EF\u8FD8\u539F\uFF09\u2014\u2014\u4E0D\u4F1A\u6C61\u67D3\u5F53\u524D\u5BF9\u8BDD\uFF0C\u4E5F\u4E0D\u5360\u4F60\u7684\u5BF9\u8BDD\u8F6E\u6B21\u3002"
3407
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "\u8FD9\u4E2A\u4F1A\u8BDD\u7684\u7B2C\u4E00\u6761\u6D88\u606F" }),
3408
+ '\u4E0A\u9644\u52A0\uFF08\u4E4B\u540E\u4E0D\u518D\u9644\u52A0\uFF0C\u5237\u65B0\u9875\u9762\u4E5F\u4E0D\u4F1A\u91CD\u590D\uFF09\u3002 \u591A\u6761\u6309\u5217\u8868\u987A\u5E8F\u62FC\u63A5\uFF0C\u8F93\u5165\u6846\u91CC\u4E0D\u63D0\u524D\u663E\u793A\u3002 \u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\u4F1A\u7528\u53E6\u4E00\u4E2A AI \u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u6574\u7406\u6210\u4E00\u6761\u80FD\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C \u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846\uFF08Ctrl+Z \u53EF\u8FD8\u539F\uFF09\u2014\u2014\u4E0D\u4F1A\u6C61\u67D3\u5F53\u524D\u5BF9\u8BDD\uFF0C\u4E5F\u4E0D\u5360\u4F60\u7684\u5BF9\u8BDD\u8F6E\u6B21\u3002 0.6.0 \u8D77\u5B83\u4E0D\u518D"\u81EA\u7531\u6539\u5199"\uFF1A\u5B83\u53EA\u80FD\u4EA7\u51FA',
3409
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "\u80FD\u6307\u56DE\u4F60\u539F\u8BDD\u67D0\u4E00\u53E5\u8BDD" }),
3410
+ '\u7684\u6761\u76EE\uFF0C \u5BBF\u4E3B\u9010\u6761\u505A\u5B57\u9762\u6BD4\u5BF9\uFF0C\u5BF9\u4E0D\u4E0A\u5C31\u4E22\u6389\u90A3\u4E00\u6761\u5E76\u5728\u72B6\u6001\u884C\u91CC\u8BB0\u8D26 \u2014\u2014 \u6240\u4EE5"\u66FF\u4F60\u53D1\u660E\u4E00\u6761\u4F60\u6CA1\u8BF4\u8FC7\u7684\u9700\u6C42"\u5728\u7ED3\u6784\u4E0A\u505A\u4E0D\u5230\u3002\u4E0B\u9762\u53EF\u4EE5\u6539\u6BCF\u4E00\u6863\u7528\u7684\u63D0\u793A\u8BCD\u3002'
3185
3411
  ] }),
3186
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
3187
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowText, children: [
3188
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: "\u4F18\u5316\u5F3A\u5EA6" }),
3189
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowDesc, children: OPTIMIZER_TIERS.find((item) => item.id === settings.optimizerTier)?.hint ?? "" })
3412
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
3413
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowText, children: [
3414
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: "\u4F18\u5316\u5F3A\u5EA6" }),
3415
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowDesc, children: OPTIMIZER_TIERS.find((item) => item.id === settings.optimizerTier)?.hint ?? "" })
3190
3416
  ] }),
3191
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: OPTIMIZER_TIERS.map((item) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3417
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: OPTIMIZER_TIERS.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3192
3418
  "button",
3193
3419
  {
3194
3420
  type: "button",
@@ -3202,12 +3428,22 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3202
3428
  item.id
3203
3429
  )) })
3204
3430
  ] }),
3205
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
3206
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: rowText, children: [
3207
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowTitle, children: "\u5FEB\u6377\u6307\u4EE4\u6E05\u5355" }),
3208
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: rowDesc, children: "\u5206\u7C7B\u5728\u8FD9\u91CC\u7BA1\u7406\uFF08\u9762\u677F\u91CC\u53EA\u505A\u5207\u6362\uFF09\uFF1B\u5185\u7F6E 9 \u6761\u53EF\u4EE5\u76F4\u63A5\u7528\uFF0C\u6539\u5B8C\u8BB0\u5F97\u70B9\u300C\u4FDD\u5B58\u4FEE\u6539\u300D\u3002" })
3431
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3432
+ OptimizerPromptEditor,
3433
+ {
3434
+ tier: settings.optimizerTier,
3435
+ value: settings[optimizerPromptFieldOf(settings.optimizerTier)],
3436
+ onChange: (next) => {
3437
+ actions.setField(optimizerPromptFieldOf(settings.optimizerTier), next);
3438
+ }
3439
+ }
3440
+ ),
3441
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...row, borderTop: "none", flexDirection: "column", alignItems: "stretch", gap: 8 }, children: [
3442
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: rowText, children: [
3443
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowTitle, children: "\u5FEB\u6377\u6307\u4EE4\u6E05\u5355" }),
3444
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: rowDesc, children: "\u5206\u7C7B\u5728\u8FD9\u91CC\u7BA1\u7406\uFF08\u9762\u677F\u91CC\u53EA\u505A\u5207\u6362\uFF09\uFF1B\u5185\u7F6E 9 \u6761\u53EF\u4EE5\u76F4\u63A5\u7528\uFF0C\u6539\u5B8C\u8BB0\u5F97\u70B9\u300C\u4FDD\u5B58\u4FEE\u6539\u300D\u3002" })
3209
3445
  ] }),
3210
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3446
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3211
3447
  QuickPromptsEditor,
3212
3448
  {
3213
3449
  book,
@@ -3227,7 +3463,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3227
3463
  ]
3228
3464
  }
3229
3465
  ),
3230
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3466
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3231
3467
  FoldCard,
3232
3468
  {
3233
3469
  name: "\u8BBE\u7F6E\u9762\u677F",
@@ -3238,33 +3474,21 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3238
3474
  actions.setField(PANEL_ENABLED_FIELD, next);
3239
3475
  }
3240
3476
  },
3241
- controls: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3242
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3243
- MiniToggle,
3244
- {
3245
- label: "\u5BFC\u822A\u6EDA\u52A8",
3246
- checked: settings.panelScroll,
3247
- onChange: (next) => {
3248
- actions.setField(PANEL_SCROLL_FIELD, next);
3249
- }
3250
- }
3251
- ),
3252
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3253
- MiniToggle,
3254
- {
3255
- label: "\u8FB9\u7F18\u7F29\u653E",
3256
- checked: settings.panelResize,
3257
- onChange: (next) => {
3258
- actions.setField(PANEL_RESIZE_FIELD, next);
3259
- }
3477
+ controls: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3478
+ MiniToggle,
3479
+ {
3480
+ label: "\u8FB9\u7F18\u7F29\u653E",
3481
+ checked: settings.panelResize,
3482
+ onChange: (next) => {
3483
+ actions.setField(PANEL_RESIZE_FIELD, next);
3260
3484
  }
3261
- )
3262
- ] }),
3485
+ }
3486
+ ),
3263
3487
  children: [
3264
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: bodyLead, children: "\u63D2\u4EF6\u88C5\u5F97\u591A\u65F6\u8BBE\u7F6E\u6761\u76EE\u5F88\u957F\uFF1A\u5F00\u542F\u300C\u5BFC\u822A\u53EF\u6EDA\u52A8\u300D\u540E\uFF0C\u5DE6\u4FA7\u5BFC\u822A\u5728\u6EA2\u51FA\u65F6\u4F1A\u51FA\u73B0\u6EDA\u52A8\u6761\u3002 \u5F00\u542F\u300C\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\u300D\u540E\uFF0C\u628A\u9F20\u6807\u79FB\u5230\u8BBE\u7F6E\u9762\u677F\u7684\u8FB9\u6216\u89D2\u4E0A\uFF08\u51FA\u73B0\u9AD8\u4EAE\u6216\u5149\u6807\u53D8\u5316\uFF09\u62D6\u52A8\u5373\u53EF\u6539\u53D8\u9762\u677F\u5927\u5C0F\uFF0C \u5C3A\u5BF8\u4F1A\u8BB0\u4F4F\uFF0C\u4E0B\u6B21\u6253\u5F00\u4FDD\u6301\u3002\uFF08\u8FD9\u4E24\u4E2A\u5F00\u5173\u5728\u6807\u9898\u884C\u4E0A\u3002\uFF09" }),
3265
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginTop: 10 }, children: [
3266
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: rowDesc, children: "\u5C3A\u5BF8\u9884\u8BBE\uFF1A" }),
3267
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3488
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: bodyLead, children: "\u5BFC\u822A\u5217\u7684\u6EDA\u52A8\u7531 DSH \u5B98\u65B9\u7684\u8BBE\u7F6E\u9875\u81EA\u5DF1\u8D1F\u8D23\uFF0C\u672C\u63D2\u4EF6\u4E0D\u518D\u4ECB\u5165\u3002 \u5F00\u542F\u300C\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\u300D\u540E\uFF0C\u628A\u9F20\u6807\u79FB\u5230\u8BBE\u7F6E\u9762\u677F\u7684\u8FB9\u6216\u89D2\u4E0A\uFF08\u51FA\u73B0\u9AD8\u4EAE\u6216\u5149\u6807\u53D8\u5316\uFF09\u62D6\u52A8\u5373\u53EF\u6539\u53D8\u9762\u677F\u5927\u5C0F\uFF0C \u5C3A\u5BF8\u4F1A\u8BB0\u4F4F\uFF0C\u4E0B\u6B21\u6253\u5F00\u4FDD\u6301\u3002\uFF08\u8FD9\u4E2A\u5F00\u5173\u5728\u6807\u9898\u884C\u4E0A\u3002\uFF09" }),
3489
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginTop: 10 }, children: [
3490
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: rowDesc, children: "\u5C3A\u5BF8\u9884\u8BBE\uFF1A" }),
3491
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3268
3492
  "button",
3269
3493
  {
3270
3494
  type: "button",
@@ -3276,7 +3500,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3276
3500
  children: "\u9ED8\u8BA4\uFF08800\uFF09"
3277
3501
  }
3278
3502
  ),
3279
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3503
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3280
3504
  "button",
3281
3505
  {
3282
3506
  type: "button",
@@ -3288,7 +3512,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3288
3512
  children: "\u7D27\u51D1\uFF08640\xD7600\uFF09"
3289
3513
  }
3290
3514
  ),
3291
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3515
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3292
3516
  "button",
3293
3517
  {
3294
3518
  type: "button",
@@ -3304,7 +3528,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3304
3528
  ]
3305
3529
  }
3306
3530
  ),
3307
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3531
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3308
3532
  FoldCard,
3309
3533
  {
3310
3534
  name: "OpenCode \u8BF7\u6C42\u5934",
@@ -3316,9 +3540,9 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3316
3540
  }
3317
3541
  },
3318
3542
  children: [
3319
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: hintError, children: "\u26A0\uFE0F \u8BF7\u4F7F\u7528\u81EA\u5B9A\u4E49\u7684 OpenCode API \u5730\u5740\uFF0C\u4E0D\u8981\u7528 DSH \u81EA\u5E26\u7684 API \u5730\u5740\u914D\u7F6E\uFF1A \u7528\u81EA\u5E26\u7684\u914D\u7F6E\u65E0\u6CD5\u4E0A\u4F20\u56FE\u7247\uFF0C\u4E00\u65E6\u53D1\u9001\u56FE\u7247\u5C31\u4F1A\u62A5\u9519\u3002" }),
3320
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: bodyLead, children: "OpenCode \u7684\u63A5\u53E3\u8981\u6C42\u5BA2\u6237\u7AEF\u6BCF\u6B21\u8BF7\u6C42\u90FD\u5E26\u4E0A\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID \u8BF7\u6C42\u5934\uFF08\u5B98\u65B9 Go \u6587\u6863 \u300C\u53EF\u4EE5\u5728\u54EA\u91CC\u4F7F\u7528\uFF1F\u300D\u7B2C 3 \u6761\uFF1A\u4E3A\u6BCF\u6BB5\u5BF9\u8BDD\u5728 x-opencode-session \u4E2D\u53D1\u9001\u4F1A\u8BDD ID\uFF0C \u4EE5\u4FBF\u5176\u4F18\u5316\u8DEF\u7531\u4E0E\u63D0\u793A\u8BCD\u7F13\u5B58\uFF09\u3002DSH \u7684\u8BBE\u7F6E\u9875\u4E0D\u63D0\u4F9B\u8BF7\u6C42\u5934\u7F16\u8F91\u5668\uFF0C\u6240\u4EE5\u8FD9\u91CC\u76F4\u63A5\u628A\u5B83\u5199\u8FDB llm-pi-ai \u7684 provider \u914D\u7F6E\u2014\u2014\u4E0B\u4E00\u6B21\u6A21\u578B\u8BF7\u6C42\u5C31\u751F\u6548\uFF0C\u4E0D\u7528\u91CD\u542F\uFF0C\u4E5F\u4E0D\u7528\u624B\u5DE5\u6539 settings.yaml\u3002 \u53EA\u5BF9 llm-pi-ai \u91CC\u300C\u5DF2\u5B58\u5728\u300D\u7684 opencode \u7CFB\u8DEF\u7531\u751F\u6548\uFF0C\u4E0D\u4F1A\u51ED\u7A7A\u65B0\u5EFA provider\uFF1B \u603B\u5F00\u5173\u5173\u95ED\u6216\u672C\u680F\u76EE\u505C\u7528\u65F6\uFF0C\u5199\u5165\u7684\u5934\u4F1A\u81EA\u52A8\u64A4\u9500\u3002" }),
3321
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3543
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: hintError, children: "\u26A0\uFE0F \u8BF7\u4F7F\u7528\u81EA\u5B9A\u4E49\u7684 OpenCode API \u5730\u5740\uFF0C\u4E0D\u8981\u7528 DSH \u81EA\u5E26\u7684 API \u5730\u5740\u914D\u7F6E\uFF1A \u7528\u81EA\u5E26\u7684\u914D\u7F6E\u65E0\u6CD5\u4E0A\u4F20\u56FE\u7247\uFF0C\u4E00\u65E6\u53D1\u9001\u56FE\u7247\u5C31\u4F1A\u62A5\u9519\u3002" }),
3544
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: bodyLead, children: "OpenCode \u7684\u63A5\u53E3\u8981\u6C42\u5BA2\u6237\u7AEF\u6BCF\u6B21\u8BF7\u6C42\u90FD\u5E26\u4E0A\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID \u8BF7\u6C42\u5934\uFF08\u5B98\u65B9 Go \u6587\u6863 \u300C\u53EF\u4EE5\u5728\u54EA\u91CC\u4F7F\u7528\uFF1F\u300D\u7B2C 3 \u6761\uFF1A\u4E3A\u6BCF\u6BB5\u5BF9\u8BDD\u5728 x-opencode-session \u4E2D\u53D1\u9001\u4F1A\u8BDD ID\uFF0C \u4EE5\u4FBF\u5176\u4F18\u5316\u8DEF\u7531\u4E0E\u63D0\u793A\u8BCD\u7F13\u5B58\uFF09\u3002DSH \u7684\u8BBE\u7F6E\u9875\u4E0D\u63D0\u4F9B\u8BF7\u6C42\u5934\u7F16\u8F91\u5668\uFF0C\u6240\u4EE5\u8FD9\u91CC\u76F4\u63A5\u628A\u5B83\u5199\u8FDB llm-pi-ai \u7684 provider \u914D\u7F6E\u2014\u2014\u4E0B\u4E00\u6B21\u6A21\u578B\u8BF7\u6C42\u5C31\u751F\u6548\uFF0C\u4E0D\u7528\u91CD\u542F\uFF0C\u4E5F\u4E0D\u7528\u624B\u5DE5\u6539 settings.yaml\u3002 \u53EA\u5BF9 llm-pi-ai \u91CC\u300C\u5DF2\u5B58\u5728\u300D\u7684 opencode \u7CFB\u8DEF\u7531\u751F\u6548\uFF0C\u4E0D\u4F1A\u51ED\u7A7A\u65B0\u5EFA provider\uFF1B \u603B\u5F00\u5173\u5173\u95ED\u6216\u672C\u680F\u76EE\u505C\u7528\u65F6\uFF0C\u5199\u5165\u7684\u5934\u4F1A\u81EA\u52A8\u64A4\u9500\u3002" }),
3545
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3322
3546
  TextFieldRow,
3323
3547
  {
3324
3548
  title: "\u5934\u540D",
@@ -3331,7 +3555,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3331
3555
  }
3332
3556
  }
3333
3557
  ),
3334
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3558
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3335
3559
  TextFieldRow,
3336
3560
  {
3337
3561
  title: "\u503C",
@@ -3350,7 +3574,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3350
3574
  }
3351
3575
  }
3352
3576
  ),
3353
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3577
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3354
3578
  TextFieldRow,
3355
3579
  {
3356
3580
  title: "\u4F5C\u7528\u8DEF\u7531",
@@ -3363,14 +3587,14 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3363
3587
  }
3364
3588
  }
3365
3589
  ),
3366
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: hintInfo, children: [
3590
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: hintInfo, children: [
3367
3591
  "\u72B6\u6001\uFF1A",
3368
3592
  headerStatusText
3369
3593
  ] })
3370
3594
  ]
3371
3595
  }
3372
3596
  ),
3373
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3597
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3374
3598
  FoldCard,
3375
3599
  {
3376
3600
  name: "\u9ED8\u8BA4\u7EC8\u7AEF",
@@ -3381,7 +3605,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3381
3605
  actions.setField(TERMINAL_ENABLED_FIELD, next);
3382
3606
  }
3383
3607
  },
3384
- controls: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3608
+ controls: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3385
3609
  PillChoice,
3386
3610
  {
3387
3611
  compact: true,
@@ -3394,8 +3618,8 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3394
3618
  }
3395
3619
  ),
3396
3620
  children: [
3397
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: bodyLead, children: "Windows \u4E0A DSH \u7ED9\u6A21\u578B\u7684\u7EC8\u7AEF\u5DE5\u5177\u662F PowerShell\uFF0C\u800C\u6A21\u578B\u5BF9 bash \u8BED\u6CD5\u7684\u628A\u63E1\u660E\u663E\u66F4\u597D\u3002\u8FD9\u4E00\u680F\u628A\u7EC8\u7AEF \u6362\u6210 Git Bash\uFF1A\u6A21\u578B\u770B\u5230\u7684\u5DE5\u5177\u5C31\u53EB bash\u3001PowerShell \u90A3\u4E2A\u5DE5\u5177\u4F1A\u4ECE\u5B83\u7684\u5DE5\u5177\u5217\u8868\u91CC\u6D88\u5931\uFF0C \u547D\u4EE4\u91CC\u7684\u8DEF\u5F84\u4E0E\u5F15\u53F7\u6309 bash \u89C4\u5219\u5199\u3002\u672C\u673A\u4E0D\u9700\u8981\u88C5 Git for Windows \u5230\u9ED8\u8BA4\u76EE\u5F55\u2014\u2014\u63A2\u6D4B\u4F1A\u5148\u627E git\uFF0C\u518D\u7531\u540C\u4E00\u4E2A\u5B89\u88C5\u53CD\u63A8 bash\u3002\uFF08\u6863\u4F4D\u5728\u6807\u9898\u884C\u4E0A\uFF1A\u81EA\u52A8 / Git Bash / PowerShell\u3002\uFF09" }),
3398
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DefaultTerminalBody, { settings, setField: actions.setField, hideMode: true })
3621
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: bodyLead, children: "Windows \u4E0A DSH \u7ED9\u6A21\u578B\u7684\u7EC8\u7AEF\u5DE5\u5177\u662F PowerShell\uFF0C\u800C\u6A21\u578B\u5BF9 bash \u8BED\u6CD5\u7684\u628A\u63E1\u660E\u663E\u66F4\u597D\u3002\u8FD9\u4E00\u680F\u628A\u7EC8\u7AEF \u6362\u6210 Git Bash\uFF1A\u6A21\u578B\u770B\u5230\u7684\u5DE5\u5177\u5C31\u53EB bash\u3001PowerShell \u90A3\u4E2A\u5DE5\u5177\u4F1A\u4ECE\u5B83\u7684\u5DE5\u5177\u5217\u8868\u91CC\u6D88\u5931\uFF0C \u547D\u4EE4\u91CC\u7684\u8DEF\u5F84\u4E0E\u5F15\u53F7\u6309 bash \u89C4\u5219\u5199\u3002\u672C\u673A\u4E0D\u9700\u8981\u88C5 Git for Windows \u5230\u9ED8\u8BA4\u76EE\u5F55\u2014\u2014\u63A2\u6D4B\u4F1A\u5148\u627E git\uFF0C\u518D\u7531\u540C\u4E00\u4E2A\u5B89\u88C5\u53CD\u63A8 bash\u3002\uFF08\u6863\u4F4D\u5728\u6807\u9898\u884C\u4E0A\uFF1A\u81EA\u52A8 / Git Bash / PowerShell\u3002\uFF09" }),
3622
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DefaultTerminalBody, { settings, setField: actions.setField, hideMode: true })
3399
3623
  ]
3400
3624
  }
3401
3625
  )
@@ -3405,7 +3629,7 @@ function SettingsSection({ useLive, useBook, useBookStatus, actions }) {
3405
3629
 
3406
3630
  // src/client/QuickCommandsButton.tsx
3407
3631
  var import_react5 = require("react");
3408
- var import_jsx_runtime7 = require("react/jsx-runtime");
3632
+ var import_jsx_runtime8 = require("react/jsx-runtime");
3409
3633
  function QuickCommandsButton({
3410
3634
  useInput,
3411
3635
  inputActions,
@@ -3434,7 +3658,7 @@ function QuickCommandsButton({
3434
3658
  }, [inputActions, draft, sessionId, blank]);
3435
3659
  if (!activeSections(settings).quick) return null;
3436
3660
  const open = anchor !== null;
3437
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3661
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3438
3662
  "button",
3439
3663
  {
3440
3664
  ref,
@@ -3455,14 +3679,14 @@ function QuickCommandsButton({
3455
3679
  });
3456
3680
  },
3457
3681
  children: [
3458
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3682
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3459
3683
  "svg",
3460
3684
  {
3461
3685
  viewBox: "0 0 16 16",
3462
3686
  width: "12",
3463
3687
  height: "12",
3464
3688
  "aria-hidden": true,
3465
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3689
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3466
3690
  "path",
3467
3691
  {
3468
3692
  d: "M9.2 1.2 3.4 9.1h3.5l-0.9 5.7 6-8.1H8.4l0.8-5.5Z",
@@ -3471,7 +3695,7 @@ function QuickCommandsButton({
3471
3695
  )
3472
3696
  }
3473
3697
  ),
3474
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "\u5FEB\u6377\u6307\u4EE4" })
3698
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\u5FEB\u6377\u6307\u4EE4" })
3475
3699
  ]
3476
3700
  }
3477
3701
  );
@@ -3479,7 +3703,7 @@ function QuickCommandsButton({
3479
3703
 
3480
3704
  // src/client/QuickCommandsPanel.tsx
3481
3705
  var import_react6 = require("react");
3482
- var import_jsx_runtime8 = require("react/jsx-runtime");
3706
+ var import_jsx_runtime9 = require("react/jsx-runtime");
3483
3707
  var MARGIN = 8;
3484
3708
  var GAP = 8;
3485
3709
  function QuickCommandsPanel({
@@ -3542,7 +3766,7 @@ function QuickCommandsPanel({
3542
3766
  const tier = settings.optimizerTier;
3543
3767
  const items = active2?.prompts ?? [];
3544
3768
  const failure = status !== "" && status !== "saving" ? status : "";
3545
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3769
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3546
3770
  "div",
3547
3771
  {
3548
3772
  ref,
@@ -3550,10 +3774,10 @@ function QuickCommandsPanel({
3550
3774
  "aria-label": "\u5FEB\u6377\u6307\u4EE4",
3551
3775
  style: { ...quickPanel, left: position?.left ?? anchor.left, top: position?.top ?? anchor.bottom },
3552
3776
  children: [
3553
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: quickPanelHead, children: [
3554
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: quickPanelTitleRow, children: [
3555
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: quickPanelTitle, children: "\u5FEB\u6377\u6307\u4EE4" }),
3556
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: quickTierRow, role: "group", "aria-label": "\u4F18\u5316\u5F3A\u5EA6", children: OPTIMIZER_TIERS.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3777
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: quickPanelHead, children: [
3778
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: quickPanelTitleRow, children: [
3779
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: quickPanelTitle, children: "\u5FEB\u6377\u6307\u4EE4" }),
3780
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: quickTierRow, role: "group", "aria-label": "\u4F18\u5316\u5F3A\u5EA6", children: OPTIMIZER_TIERS.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3557
3781
  "button",
3558
3782
  {
3559
3783
  type: "button",
@@ -3571,12 +3795,12 @@ function QuickCommandsPanel({
3571
3795
  item.id
3572
3796
  )) })
3573
3797
  ] }),
3574
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3798
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3575
3799
  "button",
3576
3800
  {
3577
3801
  type: "button",
3578
3802
  disabled: busy,
3579
- title: "\u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u4EA4\u7ED9\u53E6\u4E00\u4E2A AI \u6574\u7406\u6210\u4E00\u6761\u53EF\u4EE5\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C\u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846",
3803
+ title: "\u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u4EA4\u7ED9\u53E6\u4E00\u4E2A AI \u6574\u7406\u6210\u4E00\u6761\u53EF\u4EE5\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C\u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846\u3002\u5B83\u53EA\u80FD\u4EA7\u51FA\u80FD\u6307\u56DE\u4F60\u539F\u8BDD\u67D0\u4E00\u53E5\u7684\u8865\u5168\uFF0C\u6307\u4E0D\u56DE\u53BB\u7684\u4F1A\u88AB\u4E22\u6389\u5E76\u8BB0\u8D26",
3580
3804
  style: busy ? quickPrimaryButtonDisabled : quickPrimaryButton,
3581
3805
  onMouseDown: (event) => {
3582
3806
  event.preventDefault();
@@ -3585,13 +3809,13 @@ function QuickCommandsPanel({
3585
3809
  actions.optimize();
3586
3810
  },
3587
3811
  children: [
3588
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": true, children: "\u2728" }),
3589
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: busy ? "\u4F18\u5316\u4E2D\u2026" : "\u4F18\u5316\u63D0\u793A\u8BCD" })
3812
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": true, children: "\u2728" }),
3813
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: busy ? "\u4F18\u5316\u4E2D\u2026" : "\u4F18\u5316\u63D0\u793A\u8BCD" })
3590
3814
  ]
3591
3815
  }
3592
3816
  ),
3593
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: quickCategoryRow, children: [
3594
- categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3817
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: quickCategoryRow, children: [
3818
+ categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3595
3819
  "button",
3596
3820
  {
3597
3821
  type: "button",
@@ -3608,7 +3832,7 @@ function QuickCommandsPanel({
3608
3832
  },
3609
3833
  category.id
3610
3834
  )),
3611
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3835
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3612
3836
  "button",
3613
3837
  {
3614
3838
  type: "button",
@@ -3626,14 +3850,14 @@ function QuickCommandsPanel({
3626
3850
  )
3627
3851
  ] })
3628
3852
  ] }),
3629
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: quickList, children: [
3630
- items.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: quickEmpty, children: [
3853
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: quickList, children: [
3854
+ items.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: quickEmpty, children: [
3631
3855
  "\u8FD9\u4E2A\u5206\u7C7B\u91CC\u8FD8\u6CA1\u6709\u6761\u76EE\u3002",
3632
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
3856
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("br", {}),
3633
3857
  "\u5728\u300C\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C \u2192 \u5FEB\u6377\u6307\u4EE4\u6E05\u5355\u300D\u91CC\u6DFB\u52A0\u3002"
3634
3858
  ] }),
3635
- items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
3636
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3859
+ items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
3860
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3637
3861
  "button",
3638
3862
  {
3639
3863
  type: "button",
@@ -3646,12 +3870,12 @@ function QuickCommandsPanel({
3646
3870
  actions.insert(item.prompt);
3647
3871
  },
3648
3872
  children: [
3649
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: quickItemLabel, children: item.label }),
3650
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: quickItemPreview, children: item.prompt.replace(/\s+/g, " ") })
3873
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: quickItemLabel, children: item.label }),
3874
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: quickItemPreview, children: item.prompt.replace(/\s+/g, " ") })
3651
3875
  ]
3652
3876
  }
3653
3877
  ),
3654
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3878
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3655
3879
  InsertModeControl,
3656
3880
  {
3657
3881
  compact: true,
@@ -3663,7 +3887,7 @@ function QuickCommandsPanel({
3663
3887
  }
3664
3888
  )
3665
3889
  ] }, item.id)),
3666
- active2 !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3890
+ active2 !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3667
3891
  AddPromptRow,
3668
3892
  {
3669
3893
  variant: "panel",
@@ -3678,9 +3902,9 @@ function QuickCommandsPanel({
3678
3902
  }
3679
3903
  )
3680
3904
  ] }),
3681
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: quickPanelFoot, children: [
3682
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: quickNotice, role: "status", children: notice !== "" ? notice : failure }),
3683
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3905
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: quickPanelFoot, children: [
3906
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: quickNotice, role: "status", children: notice !== "" ? notice : failure }),
3907
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3684
3908
  "span",
3685
3909
  {
3686
3910
  style: quickFootHint,
@@ -3701,28 +3925,94 @@ function QuickCommandsPanel({
3701
3925
 
3702
3926
  // src/client.tsx
3703
3927
  var name = "composer-ux";
3704
- var inject = ["slots", "settingsScope"];
3928
+ var inject = ["slots"];
3929
+ var NULL_SCOPE = {
3930
+ getSnapshot: () => ({ status: "unavailable", value: void 0 }),
3931
+ subscribe: () => () => {
3932
+ },
3933
+ set: async () => false,
3934
+ unset: async () => false,
3935
+ mutate: async () => false
3936
+ };
3705
3937
  function apply(ctx) {
3706
3938
  const slots = ctx.slots;
3707
- const scope = ctx.settingsScope.bind({ namespace: NAMESPACE });
3708
3939
  const live = (0, import_dsh_client_store.createSnapshotStore)({ ...DEFAULT_SETTINGS });
3709
3940
  const menu2 = (0, import_dsh_client_store.createSnapshotStore)(null);
3710
3941
  const panel = (0, import_dsh_client_store.createSnapshotStore)(null);
3711
3942
  const optimizing = (0, import_dsh_client_store.createSnapshotStore)(false);
3712
3943
  const panelNotice = (0, import_dsh_client_store.createSnapshotStore)("");
3944
+ const writeNotice = (0, import_dsh_client_store.createSnapshotStore)("");
3945
+ let scope = NULL_SCOPE;
3713
3946
  const sync = () => {
3714
3947
  const snapshot = scope.getSnapshot();
3715
3948
  live.set(snapshot.status === "ready" && snapshot.value !== void 0 ? { ...DEFAULT_SETTINGS, ...sanitizeSettings(snapshot.value) } : { ...DEFAULT_SETTINGS });
3716
3949
  };
3717
3950
  sync();
3718
- ctx.effect(() => scope.subscribe(sync), "composer-ux: settings sync");
3951
+ let adopted = false;
3952
+ const adoptSettings = (service, shape) => {
3953
+ if (adopted || service === null || service === void 0) return;
3954
+ const api = service;
3955
+ const next = shape === "get" ? api.get?.(NAMESPACE) : api.bind?.({ namespace: NAMESPACE });
3956
+ if (next === null || next === void 0) return;
3957
+ if (typeof next.getSnapshot !== "function") return;
3958
+ adopted = true;
3959
+ scope = next;
3960
+ sync();
3961
+ ctx.effect(() => scope.subscribe(sync), "composer-ux: settings sync");
3962
+ };
3963
+ const whenService = (deps, callback) => {
3964
+ if (typeof ctx.inject !== "function") return;
3965
+ try {
3966
+ ctx.inject(deps, callback);
3967
+ } catch (error) {
3968
+ console.warn("[composer-ux] settings service inject failed", error);
3969
+ }
3970
+ };
3971
+ whenService(["configForms"], (view) => {
3972
+ adoptSettings(view.configForms, "get");
3973
+ });
3974
+ whenService(["settingsScope"], (view) => {
3975
+ adoptSettings(view.settingsScope, "bind");
3976
+ });
3977
+ const peekService = (name2) => {
3978
+ try {
3979
+ return ctx[name2];
3980
+ } catch {
3981
+ return void 0;
3982
+ }
3983
+ };
3984
+ adoptSettings(peekService("configForms"), "get");
3985
+ adoptSettings(peekService("settingsScope"), "bind");
3986
+ const WRITE_READBACK_MS = 1200;
3719
3987
  const setField = (field, value) => {
3720
- void scope.set(field, value).catch((error) => {
3988
+ writeNotice.set("");
3989
+ const verify = typeof value === "boolean";
3990
+ void scope.set(field, value).then((accepted) => {
3991
+ if (accepted === false) {
3992
+ console.warn("[composer-ux] settings write refused", field);
3993
+ writeNotice.set(
3994
+ `\u5199\u5165\u300C${field}\u300D\u88AB\u5BBF\u4E3B\u62D2\u7EDD\u3002\u5E38\u89C1\u539F\u56E0\uFF1Aprofile \u7684\u5199\u5165\u9501\u88AB\u5360\u7528\uFF0C\u6216\u662F\u4E00\u628A\u5B64\u513F\u9501\uFF08\u786C\u6740\u91CD\u542F\u7559\u4E0B\u7684\uFF09\u2014\u2014\u89C1 README\u300C\u8BBE\u7F6E\u5199\u4E0D\u8FDB\u53BB\u300D\u4E00\u8282\uFF1B\u91CD\u542F DSH \u540E\u4ECD\u65E0\u6548\uFF0C\u5C31\u624B\u5DE5\u5220\u6389 profiles/<\u4F60\u7684 profile>/package.json.lock\u3002`
3995
+ );
3996
+ return;
3997
+ }
3998
+ if (!verify) return;
3999
+ setTimeout(() => {
4000
+ const now = live.getSnapshot()[field];
4001
+ if (now === value) return;
4002
+ console.warn("[composer-ux] settings write had no visible effect", field, now, value);
4003
+ writeNotice.set(
4004
+ `\u5199\u5165\u300C${field}\u300D\u5DF2\u88AB\u5BBF\u4E3B\u63A5\u53D7\uFF0C\u4F46\u8FD0\u884C\u65F6\u7684\u503C\u6CA1\u6709\u53D8\u5316\uFF08\u4ECD\u662F ${String(now)}\uFF09\u3002\u914D\u7F6E\u53EF\u80FD\u5DF2\u7ECF\u843D\u76D8\uFF0C\u53EA\u662F\u8FD9\u4E2A\u8FDB\u7A0B\u6CA1\u63A5\u4F4F\u2014\u2014\u91CD\u542F DSH \u5373\u53EF\u751F\u6548\u3002`
4005
+ );
4006
+ }, WRITE_READBACK_MS);
4007
+ }, (error) => {
3721
4008
  console.error("[composer-ux] settings write failed", error);
4009
+ writeNotice.set(`\u5199\u5165\u300C${field}\u300D\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`);
3722
4010
  });
3723
4011
  };
3724
4012
  const clearField = (field) => {
3725
- void scope.unset(field).catch((error) => {
4013
+ void scope.unset(field).then((accepted) => {
4014
+ if (accepted === false) console.warn("[composer-ux] settings clear refused", field);
4015
+ }, (error) => {
3726
4016
  console.error("[composer-ux] settings clear failed", error);
3727
4017
  });
3728
4018
  };
@@ -3807,7 +4097,6 @@ function apply(ctx) {
3807
4097
  MENU_MODE_FIELD,
3808
4098
  // 旧的布尔字段也一并清掉:它只是迁移线索,留着会把「恢复默认」后的档位又拉回旧值。
3809
4099
  MENU_NATIVE_FIELD,
3810
- PANEL_SCROLL_FIELD,
3811
4100
  PANEL_RESIZE_FIELD,
3812
4101
  PANEL_WIDTH_FIELD,
3813
4102
  PANEL_HEIGHT_FIELD,
@@ -3882,7 +4171,14 @@ function apply(ctx) {
3882
4171
  }
3883
4172
  replaceDraft(result.text ?? "");
3884
4173
  focusComposer();
3885
- note(`\u5DF2\u5199\u56DE\u8F93\u5165\u6846\uFF08${result.route}\uFF09\xB7 Ctrl+Z \u53EF\u8FD8\u539F`);
4174
+ const bits = [];
4175
+ if (result.fallback === true) bits.push("\u6A21\u578B\u6CA1\u6309\u6761\u76EE\u5951\u7EA6\u8F93\u51FA\uFF0C\u5DF2\u6574\u6BB5\u7167\u6536\uFF08\u672A\u6821\u9A8C\u4F9D\u636E\uFF09");
4176
+ else bits.push(`${String(result.itemCount ?? 0)} \u6761\u8865\u5168`);
4177
+ const lost = result.dropped?.length ?? 0;
4178
+ if (lost > 0) bits.push(`\u4E22\u5F03 ${String(lost)} \u6761`);
4179
+ if (result.promptSource === "custom") bits.push("\u81EA\u5B9A\u4E49\u63D0\u793A\u8BCD");
4180
+ if (result.retried === true) bits.push("\u91CD\u8BD5\u8FC7\u4E00\u6B21");
4181
+ note(`\u5DF2\u5199\u56DE\u8F93\u5165\u6846\uFF08${result.route}\uFF09\xB7 ${bits.join(" \xB7 ")} \xB7 Ctrl+Z \u53EF\u8FD8\u539F`);
3886
4182
  },
3887
4183
  (error) => {
3888
4184
  optimizing.set(false);
@@ -3909,14 +4205,17 @@ function apply(ctx) {
3909
4205
  order: 40,
3910
4206
  label: "\u8F93\u5165\u4F53\u9A8C",
3911
4207
  inject: () => ({
3912
- hooks: { live, book, bookStatus },
4208
+ hooks: { live, book, bookStatus, writeNotice },
3913
4209
  actions: {
3914
4210
  setField,
3915
4211
  clearField,
3916
4212
  resetAll,
3917
4213
  saveBook: bookActions.saveBook,
3918
4214
  reloadBook: bookActions.reload,
3919
- resetBook: bookActions.resetBook
4215
+ resetBook: bookActions.resetBook,
4216
+ dismissNotice: () => {
4217
+ writeNotice.set("");
4218
+ }
3920
4219
  }
3921
4220
  })
3922
4221
  }, SettingsSection));
@@ -3977,16 +4276,7 @@ function apply(ctx) {
3977
4276
  }, QuickCommandsPanel));
3978
4277
  ctx.effect(() => installSettingsCardStyle(), "composer-ux: settings card style");
3979
4278
  ctx.effect(() => installQuickButtonStyle(), "composer-ux: quick button style");
3980
- ctx.effect(
3981
- () => installPanelStyle(
3982
- () => {
3983
- const settings = live.getSnapshot();
3984
- return activeSections(settings).panel && settings.panelScroll;
3985
- },
3986
- (listener) => live.subscribe(listener)
3987
- ),
3988
- "composer-ux: panel style"
3989
- );
4279
+ ctx.effect(() => installPanelResizeStyle(), "composer-ux: panel resize style");
3990
4280
  ctx.effect(() => {
3991
4281
  let dispose = null;
3992
4282
  const syncInterceptors = () => {