dsh-composer-ux 0.13.0 → 0.13.1
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/CHANGELOG.md +33 -0
- package/README.en.md +4 -1
- package/README.md +11 -3
- package/lib/client.js +216 -118
- package/lib/client.js.map +3 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.13.1] — 2026-09-30(面板分两半:优化提示词 / 快捷指令二选一;修「展开后看不到 插入/重新优化/复制」)
|
|
6
|
+
|
|
7
|
+
起因(用户原话):**「现在是点击提示词优化按钮才能展开优化输入框,我想要点开快捷指令分为两个部分:一部分是优化提示词部分,一部分是快捷指令部分。」**
|
|
8
|
+
并附了一条真机发现的 bug:**「展开优化提示词内容之后我看不到复制和填入之类的按钮」**。
|
|
9
|
+
|
|
10
|
+
### 改成什么样(开工前问清并确认过的三点)
|
|
11
|
+
|
|
12
|
+
- **默认展开「快捷指令」**,标题行的**三档档位与 ✨ 优化提示词按钮始终露在外面** —— 跑一次优化永远是一步,不必先展开。
|
|
13
|
+
- 中部**二选一**:`优化提示词`(结果框)或 `快捷指令`(分类标签 + 条目列表 + 底部计数),中间一个切换按钮(▸ / ▾)换着看。
|
|
14
|
+
- **点 ✨ 或结果框出现时自动切到「优化提示词」那半**,否则刚跑出来的东西会被自己藏在收起状态里;
|
|
15
|
+
手动切回快捷指令不会被抢回去;点结果框的「✕」顺手切回快捷指令。
|
|
16
|
+
|
|
17
|
+
### 修掉的 bug(用户报的那条)
|
|
18
|
+
|
|
19
|
+
结果框原先和快捷指令列表**挤同一块固定高度**(面板 `max-height: min(60vh, 520px)` + `overflow: hidden`,
|
|
20
|
+
而结果框自身没有滚动或高度上限):内容一长(条目多 + 成品多行 + 输入框 30vh)就把列表挤到 0,
|
|
21
|
+
再继续把**自己底部那排按钮(插入输入框 / 重新优化 / 复制)顶出面板边界裁掉**。修法两条:
|
|
22
|
+
|
|
23
|
+
1. 结果框拆成「**可滚内容区 + 钉在底部的按钮行**」(`dockBody` + `dockButtonsPinned`);
|
|
24
|
+
2. 两半互斥、各自内部滚(`quickSectionBody` / `quickList` 都补上 `flex: 1 1 auto` + `min-height: 0`)。
|
|
25
|
+
|
|
26
|
+
顺带一处实现改进:自动切换原本写在 `useEffect` 里,会**先渲染一帧"快捷指令"再切**(点 ✨ 会看到面板闪一下),
|
|
27
|
+
而且 **SSR 里 effect 不跑**、渲染测试根本测不到 —— 改成 React 文档里"props 变化时同步调整 state"的渲染期写法,
|
|
28
|
+
两边一起解决(这个决定是被渲染测试逼出来的:第一版这么写时新套件里 7 条全红,红的全是这一组)。
|
|
29
|
+
|
|
30
|
+
### 内部
|
|
31
|
+
|
|
32
|
+
- 新增 `test/panel-split-render.mjs`(**20 条**,`react-dom/server` **真渲染**):默认展开哪半、两半互斥、
|
|
33
|
+
三个按钮**在最后一个滚动容器之后**、跑的时候看得到「取消」、锚点为空不渲染。
|
|
34
|
+
- `client-registration.mjs` 新增 **2.0g 节(11 条)** 源码级护栏;两半规则抽成纯函数 `client/panel-sections.ts`。
|
|
35
|
+
- 测试从 **21 套件 2160 条**涨到 **22 套件 2190 条**;变异从 **128 条**涨到 **132 条,全部咬住**
|
|
36
|
+
(EA 默认那半 / EB 有结果也不切 / EC 内容区不再自己滚 / ED 切换按钮不再换另一半)。
|
|
37
|
+
|
|
5
38
|
## [0.13.0] — 2026-09-30(结果框重启恢复 + 逐轮元数据台账 + 只读查证工具 + 发版门禁三脚本 + 证据登记表)
|
|
6
39
|
|
|
7
40
|
> 起因:用户拿社区插件 [WestFox-AwA/dsh-prompt-optimizer](https://github.com/WestFox-AwA/dsh-prompt-optimizer)
|
package/README.en.md
CHANGED
|
@@ -188,10 +188,13 @@ edited in settings; the JSON output contract is always appended and cannot be ov
|
|
|
188
188
|
| Read-only tool fence (including symlinks) / every cap / out-of-bounds rejection | `node test/optimize-tools.mjs` (66 checks against a **real temporary directory**) |
|
|
189
189
|
| Tool-loop message shape / round cap / exceptions must degrade | same file, section 6 (a fake `llm.stream` drives the whole loop; `role:'tool'` and `toolCallId` are asserted) |
|
|
190
190
|
| Tool path: off by default, fires only when enabled, **prose after lookups falls back**, no cwd ⇒ no tool at all | `test/quick-commands.mjs` 5g (13 checks) |
|
|
191
|
-
| Mutation guards really bite, and **the *named* test must be the one going red** | `npm run test:mutations`: **
|
|
191
|
+
| Mutation guards really bite, and **the *named* test must be the one going red** | `npm run test:mutations`: **132/132 bite** |
|
|
192
|
+
| Panel split + pinned result-box buttons (0.13.1) | `node test/panel-split-render.mjs` (20 checks, real `react-dom/server` render) |
|
|
192
193
|
| Release gates | `npm run gates` (tag target / packed file list / docs drift) |
|
|
193
194
|
| Three-platform CI | GitHub Actions: ubuntu / windows / macos × Node 20 |
|
|
194
195
|
|
|
196
|
+
> 0.13.1 split the panel into「优化提示词 / 快捷指令」halves with one toggle between them, and pinned the result
|
|
197
|
+
|
|
195
198
|
### Not verified (design intent, or verified on one machine only)
|
|
196
199
|
|
|
197
200
|
| Gap | Note |
|
package/README.md
CHANGED
|
@@ -143,6 +143,13 @@ dsh plugin --profile web add <你克隆或解压出来的目录>
|
|
|
143
143
|
- **0.12.0 起有记忆链**:你把成品插进输入框、改了几处、又点一次优化时,宿主会把**上一版成品**
|
|
144
144
|
一起给模型(截断 1500 字),它只需围绕变化点调整、不必从零重写(你已确认过的地方不会被改回去)。
|
|
145
145
|
不带的三种情况:同一段原文重跑(同文重试)、草稿就是上一轮成品(对成品重跑)、上一轮失败/取消;“重新优化”只在你手改过框里成品时才带。
|
|
146
|
+
- **面板分两半(0.13.1)**:中部现在是「**优化提示词**」(结果框)与「**快捷指令**」(分类 + 条目列表)**二选一**,
|
|
147
|
+
中间一个切换按钮(▸ / ▾)换着看;打开面板**默认展开快捷指令**,标题行的**三档档位与 ✨ 按钮始终露在外面**
|
|
148
|
+
—— 所以「跑一次优化」永远是一步,不必先展开。**点 ✨ 会自己切到优化那半**(否则结果被藏在收起的一半里,
|
|
149
|
+
看起来像没反应);手动切回快捷指令不会被抢回去;点结果框的「✕」会顺手切回快捷指令。
|
|
150
|
+
- **修掉「展开后看不到按钮」(0.13.1)**:以前结果框和快捷指令列表**挤同一块固定高度**,结果框一长
|
|
151
|
+
(条目多 + 成品多行)就把列表挤没、再把自己底部的**「插入输入框 / 重新优化 / 复制」顶出面板边界被裁掉**。
|
|
152
|
+
现在两半互斥、各自内部滚,而且结果框拆成「可滚内容区 + **钉在底部的按钮行**」—— 面板再矮也不裁那排按钮。
|
|
146
153
|
- **优化只从「快捷指令」面板进**(0.12.0 起):工具行只有一枚「快捷指令」按钮,点开面板再点「✨ 优化提示词」。
|
|
147
154
|
0.11.1 曾试过在工具行加一枚独立的「✨ 优化」按钮(点一下 = 开面板 + 立刻开跑),用户看到实机后明确否掉 ——
|
|
148
155
|
「我让你集合到快捷指令里的提示词优化按钮里」,于是 0.12.0 删掉它,回到单一入口。
|
|
@@ -451,6 +458,7 @@ Windows 上 DSH 给模型的终端工具是 **PowerShell**(工具名 `pwsh`)
|
|
|
451
458
|
|---|---|
|
|
452
459
|
| 结果框持久化:原子写 / 损坏隔离 / 版本信封 / 净化边界 | `node test/optimize-state.mjs`(69 条,含真路由 `GET/POST` 往返与"太大拒写");变异 DL/DM/DN/DO/DP/DQ |
|
|
453
460
|
| 重启后恢复的接线(只在框空着时恢复、去抖存盘、开关关掉不发请求) | 同上第 6 节(源码级断言 —— 组件行为在浏览器里,本仓测不到) |
|
|
461
|
+
| **面板分两半 + 结果框按钮钉底**(0.13.1) | `node test/panel-split-render.mjs`(20 条,`react-dom/server` **真渲染**:默认展开哪半、两半互斥、三个按钮在滚动区之外)+ `client-registration.mjs` 2.0g 节(11 条源码级) |
|
|
454
462
|
| 台账只记元数据、不落原文 | `node test/optimize-ledger.mjs`(50 条)+ `test/quick-commands.mjs` 5e 节:真路由跑一轮后**在磁盘上的台账文件里搜不到草稿里那个独特的词** |
|
|
455
463
|
| 台账的原因消毒(模型给的引文不再被写进磁盘) | 同上;变异 DH(去掉消毒立刻红) |
|
|
456
464
|
| 台账轮转 / 逐行容错 / 清空 | `node scripts/recap.mjs` 真进程跑:`--last` / `--session` / `--json` / `--clear` 与坏行计数都在 `test/optimize-ledger.mjs` 第 6 节 |
|
|
@@ -458,7 +466,7 @@ Windows 上 DSH 给模型的终端工具是 **PowerShell**(工具名 `pwsh`)
|
|
|
458
466
|
| 工具循环的消息形状 / 轮次封顶 / 异常必须降级 | 同上第 6 节(假 llm 驱动整条循环,逐条检查 `role:'tool'` 与 `toolCallId`) |
|
|
459
467
|
| 工具路径:默认关、开了才派、**查完吐散文必须回落**、拿不到工作目录就不派 | `test/quick-commands.mjs` 5g 节(13 条,真路由 + 假 llm) |
|
|
460
468
|
| 工具读到的内容不进台账 | 同 5g 节:断言台账里只有工具名与次数、没有读到的文件内容 |
|
|
461
|
-
| 变异守卫真的会咬人,且**必须是指定的那条测试变红** | `npm run test:mutations`:**
|
|
469
|
+
| 变异守卫真的会咬人,且**必须是指定的那条测试变红** | `npm run test:mutations`:**132 条全部咬住**(判据是 `red.some(line => line.includes(item.expect))`,不是"有红就行") |
|
|
462
470
|
| 发布门禁三条判据 | `npm run gates` 全过;`check:tag` 实测 `v0.12.0` 的 tag 名与所指提交里的版本一致 |
|
|
463
471
|
| 三平台 CI | GitHub Actions:ubuntu / windows / macos × Node 20(`npm ci → typecheck → build → test → check:pack → check:docs`) |
|
|
464
472
|
|
|
@@ -588,9 +596,9 @@ node build.mjs # 产出 lib/index.js + lib/client.js
|
|
|
588
596
|
# ⚠️ 宿主半会**内联** schemastery / cosmokit:
|
|
589
597
|
# 优先用 DSH 检出里的 vendor 副本,检出不在时退到 node_modules
|
|
590
598
|
# 里同版本的 npm 包(两者逐字节相同)——CI 上走的就是退路
|
|
591
|
-
npm test #
|
|
599
|
+
npm test # 22 个套件;当前 2190 passed, 0 failed(2026-09-29 实测;CI 三平台同样全绿)
|
|
592
600
|
# 走 scripts/run-tests.mjs:顺带把"多少套件/多少条"记进 test/.last-run.json
|
|
593
|
-
npm run test:mutations # 手动跑:变异测试,证明那套护栏真的在咬人(
|
|
601
|
+
npm run test:mutations # 手动跑:变异测试,证明那套护栏真的在咬人(132 条,须单独跑)
|
|
594
602
|
# 同样记录结果,供下面的文档门禁核对
|
|
595
603
|
npm run gates # 发版门禁三条一起跑:tag 指向 / 包内容 / 文档数字
|
|
596
604
|
npm run check:tag # ① tag 名里的版本 == 该 tag 所指提交里的 package.json 版本
|
package/lib/client.js
CHANGED
|
@@ -2770,6 +2770,9 @@ var quickPrimaryButtonDisabled = {
|
|
|
2770
2770
|
cursor: "default"
|
|
2771
2771
|
};
|
|
2772
2772
|
var quickList = {
|
|
2773
|
+
// `flex: 1 1 auto` + `minHeight: 0`:这一半被压时**自己滚**,而不是把内容顶出去。
|
|
2774
|
+
flex: "1 1 auto",
|
|
2775
|
+
minHeight: 0,
|
|
2773
2776
|
overflowY: "auto",
|
|
2774
2777
|
padding: "6px 6px 8px",
|
|
2775
2778
|
display: "flex",
|
|
@@ -2833,6 +2836,32 @@ var quickEmpty = {
|
|
|
2833
2836
|
padding: "14px 10px",
|
|
2834
2837
|
textAlign: "center"
|
|
2835
2838
|
};
|
|
2839
|
+
var quickSectionBody = {
|
|
2840
|
+
flex: "1 1 auto",
|
|
2841
|
+
minHeight: 0,
|
|
2842
|
+
display: "flex",
|
|
2843
|
+
flexDirection: "column",
|
|
2844
|
+
overflow: "hidden"
|
|
2845
|
+
};
|
|
2846
|
+
var quickSectionToggle = {
|
|
2847
|
+
display: "flex",
|
|
2848
|
+
alignItems: "center",
|
|
2849
|
+
gap: 6,
|
|
2850
|
+
width: "100%",
|
|
2851
|
+
padding: "6px 12px",
|
|
2852
|
+
border: 0,
|
|
2853
|
+
borderTop: "0.5px solid var(--dsw-alias-border-l2)",
|
|
2854
|
+
borderBottom: "0.5px solid var(--dsw-alias-border-l2)",
|
|
2855
|
+
background: "transparent",
|
|
2856
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
2857
|
+
fontSize: 11.5,
|
|
2858
|
+
textAlign: "left",
|
|
2859
|
+
cursor: "pointer"
|
|
2860
|
+
};
|
|
2861
|
+
var quickSectionToggleArrow = {
|
|
2862
|
+
width: 10,
|
|
2863
|
+
flex: "0 0 auto"
|
|
2864
|
+
};
|
|
2836
2865
|
var quickCategoryRow = {
|
|
2837
2866
|
display: "flex",
|
|
2838
2867
|
alignItems: "center",
|
|
@@ -2866,6 +2895,10 @@ var quickCategoryAdd = {
|
|
|
2866
2895
|
cursor: "pointer"
|
|
2867
2896
|
};
|
|
2868
2897
|
var dockBox = {
|
|
2898
|
+
// 撑满中部容器(`minHeight: 0` 是关键:否则弹性子项按内容高度撑,又会被裁)。
|
|
2899
|
+
flex: "1 1 auto",
|
|
2900
|
+
minHeight: 0,
|
|
2901
|
+
overflow: "hidden",
|
|
2869
2902
|
display: "flex",
|
|
2870
2903
|
flexDirection: "column",
|
|
2871
2904
|
gap: 6,
|
|
@@ -2874,6 +2907,17 @@ var dockBox = {
|
|
|
2874
2907
|
background: "var(--dsw-alias-bg-layer-1)",
|
|
2875
2908
|
border: "0.5px solid var(--dsw-alias-border-l2)"
|
|
2876
2909
|
};
|
|
2910
|
+
var dockBody = {
|
|
2911
|
+
flex: "1 1 auto",
|
|
2912
|
+
minHeight: 0,
|
|
2913
|
+
display: "flex",
|
|
2914
|
+
flexDirection: "column",
|
|
2915
|
+
gap: 6,
|
|
2916
|
+
overflowY: "auto"
|
|
2917
|
+
};
|
|
2918
|
+
var dockButtonsPinned = {
|
|
2919
|
+
flex: "0 0 auto"
|
|
2920
|
+
};
|
|
2877
2921
|
var dockHead = {
|
|
2878
2922
|
display: "flex",
|
|
2879
2923
|
alignItems: "center",
|
|
@@ -6273,6 +6317,15 @@ function useOptimizeElapsed(startedAt) {
|
|
|
6273
6317
|
return running ? seconds : 0;
|
|
6274
6318
|
}
|
|
6275
6319
|
|
|
6320
|
+
// src/client/panel-sections.ts
|
|
6321
|
+
var DEFAULT_PANEL_SECTION = "quick";
|
|
6322
|
+
function toggleSection(current) {
|
|
6323
|
+
return current === "quick" ? "optimize" : "quick";
|
|
6324
|
+
}
|
|
6325
|
+
function sectionForDock(dockPresent, current) {
|
|
6326
|
+
return dockPresent ? "optimize" : current;
|
|
6327
|
+
}
|
|
6328
|
+
|
|
6276
6329
|
// src/client/OptimizeDock.tsx
|
|
6277
6330
|
var import_react13 = require("react");
|
|
6278
6331
|
|
|
@@ -6527,28 +6580,30 @@ function OptimizeDock({ state: state2, seconds, actions }) {
|
|
|
6527
6580
|
}
|
|
6528
6581
|
)
|
|
6529
6582
|
] }),
|
|
6530
|
-
|
|
6531
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
"
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6583
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: dockBody, children: [
|
|
6584
|
+
state2.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ol", { style: dockList, children: state2.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("li", { style: dockItemRow, children: [
|
|
6585
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: dockKind, children: KIND_LABEL[item.kind] ?? item.kind }),
|
|
6586
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: dockItemText, children: item.text }),
|
|
6587
|
+
item.quote !== "" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: dockMeta, children: item.quoteSource === "none" ? `\uFF08\u6A21\u578B\u81EA\u5DF1\u8865\u7684\uFF0C\u4F9D\u636E\u4E0D\u662F\u4F60\u539F\u8BDD\uFF1A\u300C${item.quote}\u300D\uFF09` : `\uFF08\u4F9D\u636E\uFF1A"${item.quote}"\uFF09` })
|
|
6588
|
+
] }, item.id)) }),
|
|
6589
|
+
state2.dropped.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: dockDropped, children: `\u4E22\u5F03 ${String(state2.dropped.length)} \u6761\uFF1A${state2.dropped.map((row2) => row2.reason).join("\uFF1B")}` }),
|
|
6590
|
+
state2.phase === "error" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: dockError, role: "alert", children: state2.error === "" ? "\u4F18\u5316\u5931\u8D25" : state2.error }),
|
|
6591
|
+
(state2.phase === "done" || state2.phase === "cancelled") && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
6592
|
+
"textarea",
|
|
6593
|
+
{
|
|
6594
|
+
value: state2.text,
|
|
6595
|
+
onChange: (event) => {
|
|
6596
|
+
actions.edit(event.target.value);
|
|
6597
|
+
},
|
|
6598
|
+
spellCheck: false,
|
|
6599
|
+
"aria-label": "\u4F18\u5316\u540E\u7684\u63D0\u793A\u8BCD\uFF08\u53EF\u7F16\u8F91\uFF09",
|
|
6600
|
+
placeholder: state2.phase === "cancelled" ? "\u53D6\u6D88\u65F6\u8FD8\u6CA1\u6709\u6210\u54C1\uFF1A\u4E0A\u9762\u662F\u5DF2\u751F\u6210\u7684\u90E8\u5206\u3002\u70B9\u300C\u91CD\u65B0\u4F18\u5316\u300D\u8DD1\u5B8C\u4E00\u8F6E\u5C31\u80FD\u62FF\u5230\u6210\u54C1\u3002" : "\uFF08\u6210\u54C1\u4E3A\u7A7A\uFF09",
|
|
6601
|
+
style: dockEditor
|
|
6602
|
+
}
|
|
6603
|
+
),
|
|
6604
|
+
state2.phase === "done" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: dockSummaryLine, children: state2.route === "" ? dockSummary(state2) : `${dockSummary(state2)} \xB7 ${state2.route}` })
|
|
6605
|
+
] }),
|
|
6606
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { ...dockButtons, ...dockButtonsPinned }, children: [
|
|
6552
6607
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
6553
6608
|
"button",
|
|
6554
6609
|
{
|
|
@@ -6621,6 +6676,8 @@ function QuickCommandsPanel({
|
|
|
6621
6676
|
const ref = (0, import_react14.useRef)(null);
|
|
6622
6677
|
const [position, setPosition] = (0, import_react14.useState)(null);
|
|
6623
6678
|
const [activeId, setActiveId] = (0, import_react14.useState)("");
|
|
6679
|
+
const [section, setSection] = (0, import_react14.useState)(DEFAULT_PANEL_SECTION);
|
|
6680
|
+
const dockPresent = dock !== null;
|
|
6624
6681
|
const seconds = useOptimizeElapsed(busy ? startedAt : 0);
|
|
6625
6682
|
const dockRunning = dock !== null && dock.phase === "running";
|
|
6626
6683
|
const dockSeconds = useOptimizeElapsed(dockRunning && dock !== null ? dock.startedAt : 0);
|
|
@@ -6639,7 +6696,7 @@ function QuickCommandsPanel({
|
|
|
6639
6696
|
const above = anchor.bottom - height - GAP;
|
|
6640
6697
|
const top = above >= MARGIN ? above : Math.min(anchor.bottom + GAP, window.innerHeight - height - MARGIN);
|
|
6641
6698
|
setPosition({ left, top: Math.max(MARGIN, top) });
|
|
6642
|
-
}, [anchor?.left, anchor?.bottom, counts.prompts, categories.length, busy]);
|
|
6699
|
+
}, [anchor?.left, anchor?.bottom, counts.prompts, categories.length, busy, section, dock !== null]);
|
|
6643
6700
|
(0, import_react14.useEffect)(() => {
|
|
6644
6701
|
if (anchor === null) return;
|
|
6645
6702
|
const onPointerDown = (event) => {
|
|
@@ -6666,6 +6723,12 @@ function QuickCommandsPanel({
|
|
|
6666
6723
|
window.removeEventListener("resize", actions.close);
|
|
6667
6724
|
};
|
|
6668
6725
|
}, [anchor === null, actions, dockRunning]);
|
|
6726
|
+
const prevDockPresent = (0, import_react14.useRef)(false);
|
|
6727
|
+
if (prevDockPresent.current !== dockPresent) {
|
|
6728
|
+
prevDockPresent.current = dockPresent;
|
|
6729
|
+
const next = sectionForDock(dockPresent, section);
|
|
6730
|
+
if (next !== section) setSection(next);
|
|
6731
|
+
}
|
|
6669
6732
|
if (anchor === null) return null;
|
|
6670
6733
|
const tier = settings.optimizerTier;
|
|
6671
6734
|
const items = active2?.prompts ?? [];
|
|
@@ -6717,108 +6780,143 @@ function QuickCommandsPanel({
|
|
|
6717
6780
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: busy ? `\u4F18\u5316\u4E2D\u2026\uFF08${String(seconds)}s\uFF09` : "\u4F18\u5316\u63D0\u793A\u8BCD" })
|
|
6718
6781
|
]
|
|
6719
6782
|
}
|
|
6720
|
-
)
|
|
6721
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: quickCategoryRow, children: [
|
|
6722
|
-
categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
6723
|
-
"button",
|
|
6724
|
-
{
|
|
6725
|
-
type: "button",
|
|
6726
|
-
title: `${category.name}\uFF08${String(category.prompts.length)} \u6761\uFF09`,
|
|
6727
|
-
"aria-pressed": category.id === active2?.id,
|
|
6728
|
-
style: category.id === active2?.id ? quickCategoryTabActive : quickCategoryTab,
|
|
6729
|
-
onMouseDown: (event) => {
|
|
6730
|
-
event.preventDefault();
|
|
6731
|
-
},
|
|
6732
|
-
onClick: () => {
|
|
6733
|
-
setActiveId(category.id);
|
|
6734
|
-
},
|
|
6735
|
-
children: category.name
|
|
6736
|
-
},
|
|
6737
|
-
category.id
|
|
6738
|
-
)),
|
|
6739
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
6740
|
-
"button",
|
|
6741
|
-
{
|
|
6742
|
-
type: "button",
|
|
6743
|
-
style: quickCategoryAdd,
|
|
6744
|
-
disabled: categories.length >= QUICK_CATEGORY_MAX,
|
|
6745
|
-
title: "\u65B0\u589E\u4E00\u4E2A\u5206\u7C7B\uFF08\u540D\u5B57\u5230\u300C\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C\u300D\u91CC\u6539\uFF09",
|
|
6746
|
-
onMouseDown: (event) => {
|
|
6747
|
-
event.preventDefault();
|
|
6748
|
-
},
|
|
6749
|
-
onClick: () => {
|
|
6750
|
-
actions.addCategory(DEFAULT_CATEGORY_NAME);
|
|
6751
|
-
},
|
|
6752
|
-
children: "\uFF0B"
|
|
6753
|
-
}
|
|
6754
|
-
)
|
|
6755
|
-
] })
|
|
6783
|
+
)
|
|
6756
6784
|
] }),
|
|
6757
|
-
|
|
6758
|
-
|
|
6785
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
6786
|
+
"button",
|
|
6759
6787
|
{
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6788
|
+
type: "button",
|
|
6789
|
+
style: quickSectionToggle,
|
|
6790
|
+
"aria-expanded": section === "optimize",
|
|
6791
|
+
title: section === "optimize" ? "\u6536\u8D77\u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\uFF0C\u56DE\u5230\u300C\u5FEB\u6377\u6307\u4EE4\u300D" : "\u5C55\u5F00\u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\uFF08\u7ED3\u679C\u6846\u5C31\u5728\u91CC\u9762\uFF1B\u4E0A\u9762\u70B9 \u2728 \u4E5F\u4F1A\u81EA\u52A8\u5C55\u5F00\uFF09",
|
|
6792
|
+
onMouseDown: (event) => {
|
|
6793
|
+
event.preventDefault();
|
|
6794
|
+
},
|
|
6795
|
+
onClick: () => {
|
|
6796
|
+
setSection(toggleSection(section));
|
|
6797
|
+
},
|
|
6798
|
+
children: [
|
|
6799
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: quickSectionToggleArrow, "aria-hidden": true, children: section === "optimize" ? "\u25BE" : "\u25B8" }),
|
|
6800
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "\u4F18\u5316\u63D0\u793A\u8BCD" }),
|
|
6801
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { marginLeft: "auto", color: "var(--dsw-alias-label-tertiary)" }, children: section === "optimize" ? "\u70B9\u6B64\u56DE\u5230\u5FEB\u6377\u6307\u4EE4" : dockPresent ? "\u4E0A\u6B21\u7684\u7ED3\u679C\u5728\u8FD9\u513F" : "\u8FD8\u6CA1\u6709\u7ED3\u679C" })
|
|
6802
|
+
]
|
|
6769
6803
|
}
|
|
6770
|
-
)
|
|
6771
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style:
|
|
6772
|
-
|
|
6773
|
-
|
|
6804
|
+
),
|
|
6805
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: quickSectionBody, children: [
|
|
6806
|
+
dock !== null && section === "optimize" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { padding: "8px 12px 8px", flex: "1 1 auto", minHeight: 0, display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
6807
|
+
OptimizeDock,
|
|
6808
|
+
{
|
|
6809
|
+
state: dock,
|
|
6810
|
+
seconds: dockSeconds,
|
|
6811
|
+
actions: {
|
|
6812
|
+
insert: actions.dockInsert,
|
|
6813
|
+
retry: actions.dockRetry,
|
|
6814
|
+
cancel: actions.dockCancel,
|
|
6815
|
+
// 关掉结果框顺手切回快捷指令那半:此时优化半已经没内容了。
|
|
6816
|
+
close: () => {
|
|
6817
|
+
actions.dockClose();
|
|
6818
|
+
setSection(DEFAULT_PANEL_SECTION);
|
|
6819
|
+
},
|
|
6820
|
+
edit: actions.dockEdit
|
|
6821
|
+
}
|
|
6822
|
+
}
|
|
6823
|
+
) }),
|
|
6824
|
+
section === "optimize" && dock === null && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: quickEmpty, children: [
|
|
6825
|
+
"\u8FD8\u6CA1\u8DD1\u8FC7\u4F18\u5316\u3002",
|
|
6826
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("br", {}),
|
|
6827
|
+
"\u70B9\u4E0A\u9762\u7684\u300C\u2728 \u4F18\u5316\u63D0\u793A\u8BCD\u300D\u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u4EA4\u7ED9\u53E6\u4E00\u4E2A AI \u6574\u7406\u6210\u4E00\u6761\u80FD\u76F4\u63A5\u53D1\u7684\u6E05\u6670\u6307\u4EE4 \u2014\u2014 \u7ED3\u679C\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\uFF08\u53EF\u7F16\u8F91\u3001\u53EF\u63D2\u5165\u8F93\u5165\u6846\u3001\u53EF\u590D\u5236\uFF09\u3002",
|
|
6774
6828
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("br", {}),
|
|
6775
|
-
"\
|
|
6829
|
+
"\u5F3A\u5EA6\u7528\u6807\u9898\u884C\u90A3\u4E09\u4E2A\u6863\u4F4D\uFF08\u666E\u901A / \u9AD8\u7EA7 / \u6781\u7AEF\uFF09\u3002"
|
|
6776
6830
|
] }),
|
|
6777
|
-
|
|
6778
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6831
|
+
section === "quick" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
6832
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { padding: "8px 12px 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: quickCategoryRow, children: [
|
|
6833
|
+
categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
6834
|
+
"button",
|
|
6835
|
+
{
|
|
6836
|
+
type: "button",
|
|
6837
|
+
title: `${category.name}\uFF08${String(category.prompts.length)} \u6761\uFF09`,
|
|
6838
|
+
"aria-pressed": category.id === active2?.id,
|
|
6839
|
+
style: category.id === active2?.id ? quickCategoryTabActive : quickCategoryTab,
|
|
6840
|
+
onMouseDown: (event) => {
|
|
6841
|
+
event.preventDefault();
|
|
6842
|
+
},
|
|
6843
|
+
onClick: () => {
|
|
6844
|
+
setActiveId(category.id);
|
|
6845
|
+
},
|
|
6846
|
+
children: category.name
|
|
6789
6847
|
},
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6848
|
+
category.id
|
|
6849
|
+
)),
|
|
6850
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
6851
|
+
"button",
|
|
6852
|
+
{
|
|
6853
|
+
type: "button",
|
|
6854
|
+
style: quickCategoryAdd,
|
|
6855
|
+
disabled: categories.length >= QUICK_CATEGORY_MAX,
|
|
6856
|
+
title: "\u65B0\u589E\u4E00\u4E2A\u5206\u7C7B\uFF08\u540D\u5B57\u5230\u300C\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C\u300D\u91CC\u6539\uFF09",
|
|
6857
|
+
onMouseDown: (event) => {
|
|
6858
|
+
event.preventDefault();
|
|
6859
|
+
},
|
|
6860
|
+
onClick: () => {
|
|
6861
|
+
actions.addCategory(DEFAULT_CATEGORY_NAME);
|
|
6862
|
+
},
|
|
6863
|
+
children: "\uFF0B"
|
|
6804
6864
|
}
|
|
6805
|
-
|
|
6806
|
-
)
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6865
|
+
)
|
|
6866
|
+
] }) }),
|
|
6867
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: quickList, children: [
|
|
6868
|
+
items.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: quickEmpty, children: [
|
|
6869
|
+
"\u8FD9\u4E2A\u5206\u7C7B\u91CC\u8FD8\u6CA1\u6709\u6761\u76EE\u3002",
|
|
6870
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("br", {}),
|
|
6871
|
+
"\u5728\u300C\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C \u2192 \u5FEB\u6377\u6307\u4EE4\u6E05\u5355\u300D\u91CC\u6DFB\u52A0\u3002"
|
|
6872
|
+
] }),
|
|
6873
|
+
items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
6874
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
6875
|
+
"button",
|
|
6876
|
+
{
|
|
6877
|
+
type: "button",
|
|
6878
|
+
title: item.prompt,
|
|
6879
|
+
style: quickItem,
|
|
6880
|
+
onMouseDown: (event) => {
|
|
6881
|
+
event.preventDefault();
|
|
6882
|
+
},
|
|
6883
|
+
onClick: () => {
|
|
6884
|
+
actions.insert(item.prompt);
|
|
6885
|
+
},
|
|
6886
|
+
children: [
|
|
6887
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: quickItemLabel, children: item.label }),
|
|
6888
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: quickItemPreview, children: item.prompt.replace(/\s+/g, " ") })
|
|
6889
|
+
]
|
|
6890
|
+
}
|
|
6891
|
+
),
|
|
6892
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
6893
|
+
InsertModeControl,
|
|
6894
|
+
{
|
|
6895
|
+
compact: true,
|
|
6896
|
+
label: item.label,
|
|
6897
|
+
mode: insertModeOf(item),
|
|
6898
|
+
onChange: (mode) => {
|
|
6899
|
+
actions.setInsertMode(item.id, mode);
|
|
6900
|
+
}
|
|
6901
|
+
}
|
|
6902
|
+
)
|
|
6903
|
+
] }, item.id)),
|
|
6904
|
+
active2 !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
6905
|
+
AddPromptRow,
|
|
6906
|
+
{
|
|
6907
|
+
variant: "panel",
|
|
6908
|
+
book,
|
|
6909
|
+
categoryId: active2.id,
|
|
6910
|
+
onAdd: () => {
|
|
6911
|
+
actions.addPrompt(active2.id);
|
|
6912
|
+
},
|
|
6913
|
+
onMove: (promptId) => {
|
|
6914
|
+
actions.movePrompt(promptId, active2.id);
|
|
6915
|
+
}
|
|
6916
|
+
}
|
|
6917
|
+
)
|
|
6918
|
+
] })
|
|
6919
|
+
] })
|
|
6822
6920
|
] }),
|
|
6823
6921
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: quickPanelFoot, children: [
|
|
6824
6922
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: quickNotice, role: "status", children: notice !== "" ? notice : failure }),
|