dsh-better-dsh 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -15
- package/docs/DEVELOPMENT.md +7 -7
- package/docs/UI-KIT.md +67 -20
- package/package.json +5 -5
- package/skills/brainstorming/SKILL.md +3 -1
- package/skills/brainstorming/spec-document-reviewer-prompt.md +2 -2
- package/skills/code-review/SKILL.md +2 -2
- package/skills/dev/SKILL.md +6 -4
- package/skills/exec/SKILL.md +38 -17
- package/skills/main-agent-driven-development/SKILL.md +9 -6
- package/src/client.js +61 -89
package/README.md
CHANGED
|
@@ -55,17 +55,17 @@
|
|
|
55
55
|
|
|
56
56
|
```sh
|
|
57
57
|
# npm
|
|
58
|
-
dsh plugin --profile <profile> add dsh-better-dsh@0.
|
|
58
|
+
dsh plugin --profile <profile> add dsh-better-dsh@0.11.0
|
|
59
59
|
|
|
60
60
|
# 或从 GitHub tag 安装
|
|
61
|
-
dsh plugin --profile <profile> add github:omdsh-dev/dsh-better-dsh#v0.
|
|
61
|
+
dsh plugin --profile <profile> add github:omdsh-dev/dsh-better-dsh#v0.11.0
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
> 安装、升级或换包后必须**重启对应 profile**;只刷新网页不够。
|
|
65
65
|
>
|
|
66
66
|
> 不要同时显式添加 Better DSH 和独立插件 bundle:行实例仍只有一个,但 DSH 0.2.2-rc.1 会把同一 id 的配置写入拒绝为只读。只保留一个显式入口。
|
|
67
67
|
|
|
68
|
-
本轮版本:**Better DSH `0.
|
|
68
|
+
本轮版本:**Better DSH `0.11.0`**,搭配 goal `0.4.2`、subagent `0.5.1`、compact `0.4.0`、ask-user `0.3.2`、ptc `0.2.0`。
|
|
69
69
|
|
|
70
70
|
## 架构
|
|
71
71
|
|
|
@@ -120,7 +120,7 @@ Better DSH 的 bundle patch 直接声明这些行;DSH 不会自动应用传递
|
|
|
120
120
|
| 技能 | 用途 |
|
|
121
121
|
|---|---|
|
|
122
122
|
| `/brainstorming` | 把大型需求设计为获批的主 Spec 与子 Spec |
|
|
123
|
-
| `/exec` |
|
|
123
|
+
| `/exec` | 先选自动 / 仅质量档 / 仅快速档;按依赖分波并行实现,子任务按需 CR,验证与合并后保留最终整体 CR |
|
|
124
124
|
| `/dev` | 实现与审查节点的 prompt、报告结构与失败契约 |
|
|
125
125
|
| `/main-agent-driven-development` | 实现一个边界明确的单个任务 |
|
|
126
126
|
| `/tdd` | 测试先行、红绿循环、测试边界与反模式 |
|
|
@@ -128,6 +128,8 @@ Better DSH 的 bundle patch 直接声明这些行;DSH 不会自动应用传递
|
|
|
128
128
|
| `/code-review` | 并行检查仓库标准与原始需求,并排报告 |
|
|
129
129
|
| `/handoff` | 把当前上下文整理为交接文档;仅由用户手动触发 |
|
|
130
130
|
|
|
131
|
+
`/exec` 的选档约束实现与修复,所有 CR 始终使用质量档;超时未选默认自动,普通任务用快速档,特别难或实际遇阻时可升质量档。等待子代理每次使用至少 30 分钟的超时窗口,提前完成即返回,不因等待超时催促或换人。所有审查与复审节点仅由顶层主 agent 派发;子 agent(包括 reviewer)直接完成分配的工作并向主 agent 返回结果或审查需求,不再派发审查节点。
|
|
132
|
+
|
|
131
133
|
技能需要在所选预设中挂载 DSH 的技能工具;两套工程预设已挂载。
|
|
132
134
|
</details>
|
|
133
135
|
|
|
@@ -181,10 +183,10 @@ Better DSH 包详情里的「集成设置」按 Core、Subagents、Compaction、
|
|
|
181
183
|
# 旧入口
|
|
182
184
|
dsh plugin --profile <profile> remove @menghuan1918/dsh-apollo
|
|
183
185
|
# 新入口
|
|
184
|
-
dsh plugin --profile <profile> add dsh-better-dsh@0.
|
|
186
|
+
dsh plugin --profile <profile> add dsh-better-dsh@0.11.0
|
|
185
187
|
# subagent 独立安装的用户
|
|
186
188
|
dsh plugin --profile <profile> remove @menghuan1918/dsh-better-subagent
|
|
187
|
-
dsh plugin --profile <profile> add @oh-my-dsh/dsh-better-subagent@0.5.
|
|
189
|
+
dsh plugin --profile <profile> add @oh-my-dsh/dsh-better-subagent@0.5.1
|
|
188
190
|
```
|
|
189
191
|
|
|
190
192
|
<details>
|
|
@@ -207,10 +209,10 @@ dsh plugin --profile <profile> add @oh-my-dsh/dsh-better-subagent@0.5.0
|
|
|
207
209
|
五个插件都可以单独安装;独立安装和 Better DSH 组合使用的是**同一组稳定行**。
|
|
208
210
|
|
|
209
211
|
```sh
|
|
210
|
-
dsh plugin --profile <profile> add dsh-better-goal@0.4.
|
|
211
|
-
dsh plugin --profile <profile> add @oh-my-dsh/dsh-better-subagent@0.5.
|
|
212
|
-
dsh plugin --profile <profile> add dsh-better-compact@0.
|
|
213
|
-
dsh plugin --profile <profile> add dsh-better-ask-user@0.3.
|
|
212
|
+
dsh plugin --profile <profile> add dsh-better-goal@0.4.2
|
|
213
|
+
dsh plugin --profile <profile> add @oh-my-dsh/dsh-better-subagent@0.5.1
|
|
214
|
+
dsh plugin --profile <profile> add dsh-better-compact@0.4.0
|
|
215
|
+
dsh plugin --profile <profile> add dsh-better-ask-user@0.3.2 dsh-better-ptc@0.2.0
|
|
214
216
|
```
|
|
215
217
|
|
|
216
218
|
<details>
|
|
@@ -243,11 +245,11 @@ dsh plugin --profile <profile> add dsh-better-ask-user@0.3.1 dsh-better-ptc@0.2.
|
|
|
243
245
|
**发布顺序**:先发布独立包,再发布 Better DSH(精确依赖必须已存在):
|
|
244
246
|
|
|
245
247
|
1. `dsh-better-ptc@0.2.0`(不变)
|
|
246
|
-
2. `dsh-better-ask-user@0.3.
|
|
247
|
-
3. `dsh-better-compact@0.
|
|
248
|
-
4. `dsh-better-goal@0.4.
|
|
249
|
-
5. `@oh-my-dsh/dsh-better-subagent@0.5.
|
|
250
|
-
6. `dsh-better-dsh@0.
|
|
248
|
+
2. `dsh-better-ask-user@0.3.2`
|
|
249
|
+
3. `dsh-better-compact@0.4.0`
|
|
250
|
+
4. `dsh-better-goal@0.4.2`
|
|
251
|
+
5. `@oh-my-dsh/dsh-better-subagent@0.5.1`
|
|
252
|
+
6. `dsh-better-dsh@0.11.0`
|
|
251
253
|
|
|
252
254
|
各仓库使用 npm trusted publishing(OIDC);创建对应 GitHub Release 会发布 tag 指向的版本。旧包 `@menghuan1918/dsh-apollo` 与 `@menghuan1918/dsh-better-subagent` 已标记 deprecate,仅作为历史入口保留。
|
|
253
255
|
</details>
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
面向维护者、集成者和需要排查装配问题的用户。用户安装与配置请看 [README](../README.md);本文保留 DSH 插件的实现细节、旧配置迁移、组合安装边界与验证方法。
|
|
4
4
|
|
|
5
|
-
当前实现版本:`0.
|
|
5
|
+
当前实现版本:`0.11.0`;npm 包名是 `dsh-better-dsh`。纯 ESM,无构建步骤;宿主浏览器半边是直接加载的闭包工厂。旧 `Apollo` 名称只保留在迁移、历史兼容和旧包 deprecate 说明里。
|
|
6
6
|
|
|
7
7
|
## 目录
|
|
8
8
|
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
|
|
34
34
|
| 依赖 | 版本 | 所有权 |
|
|
35
35
|
|---|---|---|
|
|
36
|
-
| `dsh-better-goal` | `0.4.
|
|
37
|
-
| `@oh-my-dsh/dsh-better-subagent` | `0.5.
|
|
38
|
-
| `dsh-better-compact` | `0.
|
|
39
|
-
| `dsh-better-ask-user` | `0.3.
|
|
36
|
+
| `dsh-better-goal` | `0.4.2` | 目标域(`questionTimeoutSeconds` 已弃用、仅保留读取) |
|
|
37
|
+
| `@oh-my-dsh/dsh-better-subagent` | `0.5.1` | 子代理 CLI/等待/child guard/分档/设置页;注册 `wait_subagent` PTC 豁免 |
|
|
38
|
+
| `dsh-better-compact` | `0.4.0` | 压缩 companion + engine + 设置页/诊断 |
|
|
39
|
+
| `dsh-better-ask-user` | `0.3.2` | 官方 `ask_user_question` 入参/返回 + 插件超时等待 + 历史预览行;注册 PTC 豁免;旧 goal 等待迁移 |
|
|
40
40
|
| `dsh-better-ptc` | `0.2.0` | 单例 PTC deadline 豁免服务 |
|
|
41
41
|
| `@deepseek-ai/schemastery` | `~3.19.0` | Better DSH 行 Config |
|
|
42
42
|
| `react` | peer | 宿主提供 |
|
|
@@ -319,7 +319,7 @@ DSH_PACKAGE_ROOT="/…/node_modules/@deepseek-ai/dsh" npm run prompts
|
|
|
319
319
|
### npm 安装
|
|
320
320
|
|
|
321
321
|
```sh
|
|
322
|
-
dsh plugin --profile <profile> add dsh-better-dsh@0.10.
|
|
322
|
+
dsh plugin --profile <profile> add dsh-better-dsh@0.10.1
|
|
323
323
|
```
|
|
324
324
|
|
|
325
325
|
包发布后即可用此命令安装,并带入五个精确依赖、应用三份 bundle patch。安装后需要重启对应 profile 的 DSH 进程。本轮版本与精确依赖见上述包清单;发布后需重新验证 registry 干净安装。
|
|
@@ -381,7 +381,7 @@ dsh plugin --profile <profile> remove @menghuan1918/dsh-apollo # 旧包;新
|
|
|
381
381
|
|
|
382
382
|
1. 先发布 `dsh-better-ptc@0.2.0`、`dsh-better-ask-user@0.3.1`、`@oh-my-dsh/dsh-better-subagent@0.5.0`、`dsh-better-goal@0.4.1`、`dsh-better-compact@0.3.1`(各自仓库的 Release);
|
|
383
383
|
2. 在官方 registry(`https://registry.npmjs.org/`)确认五个版本可取得、可安装;
|
|
384
|
-
3. 再把 Better DSH 的精确依赖指向已发布版本,推已验证的发布提交及 tag 并发布 Better DSH Release(本轮为 `v0.10.
|
|
384
|
+
3. 再把 Better DSH 的精确依赖指向已发布版本,推已验证的发布提交及 tag 并发布 Better DSH Release(本轮为 `v0.10.1`);
|
|
385
385
|
4. 子包版本可取得前,不要把指向它们的精确依赖推到 Apollo main,否则 `npm install` / GitHub 源码安装会 404。
|
|
386
386
|
|
|
387
387
|
## 测试与冒烟
|
package/docs/UI-KIT.md
CHANGED
|
@@ -22,10 +22,10 @@ component rules; do not hard-code surfaces.
|
|
|
22
22
|
| surface sunken | `color-mix(in srgb, ink-1 4%, canvas)` | same rule |
|
|
23
23
|
| ink 1 / 2 / 3 | `--dsw-alias-label-primary/secondary/tertiary` | host dark labels |
|
|
24
24
|
| line 1 / 2 / 3 | `--dsw-alias-border-l1/l2/l3` | host dark borders |
|
|
25
|
-
| accent |
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
| accent text |
|
|
25
|
+
| accent / focus | `--dsw-alias-state-business-primary` | host dark business color |
|
|
26
|
+
| primary action / switch fill | `--dsw-alias-button-primary-fill` | host dark button fill |
|
|
27
|
+
| primary action foreground | `--dsw-alias-label-primary-foreground` | host dark foreground |
|
|
28
|
+
| accent text | `color-mix(in srgb, accent 70%, ink-1)` | same rule |
|
|
29
29
|
| accent soft | `color-mix(in srgb, accent 10%, transparent)` | 14% |
|
|
30
30
|
| success / danger / warn | `--dsw-alias-state-*` | host dark state tokens |
|
|
31
31
|
| radius sm / md / lg / xl | `6 / 8 / 10 / 12px` | same |
|
|
@@ -55,40 +55,85 @@ Rules:
|
|
|
55
55
|
- Rail 200px: 36px items, 8px radius. Active = accent-soft background +
|
|
56
56
|
accent-text + 1px line; no left decoration bar.
|
|
57
57
|
- Content padding 24px 32px; each page is a max-920px column, centered.
|
|
58
|
-
- Narrow `<=
|
|
59
|
-
padding 16px
|
|
58
|
+
- Narrow `<= 800px`: rail becomes a horizontal scrolling tab strip; content
|
|
59
|
+
padding 16px. At `<= 640px` the dialog fills the viewport with no outer
|
|
60
|
+
margin or corner radius.
|
|
60
61
|
|
|
61
62
|
### Settings page
|
|
62
63
|
|
|
63
64
|
- Content column `max-width: 920px; margin: 0 auto`.
|
|
64
65
|
- Page title 20/28/500, letter-spacing -0.01em.
|
|
65
|
-
- Section
|
|
66
|
-
- Setting row: label 13/500;
|
|
67
|
-
|
|
66
|
+
- Section label 12/500, ink-3, no rule; section spacing 24px.
|
|
67
|
+
- Setting row: label 13/500; control right-aligned. Add one neutral consequence
|
|
68
|
+
line (12/ink-3) only when the label cannot explain the choice. Row padding
|
|
69
|
+
10–12px with a hover surface; no per-row divider. Explain model recommendations
|
|
70
|
+
and their scope where they are edited; do not hide essential effects in
|
|
71
|
+
screen-reader-only text.
|
|
72
|
+
- Dividers are reserved for group boundaries (footer, cards, inputs,
|
|
73
|
+
selectable rows). A form of anonymous horizontal rules between every row is a
|
|
74
|
+
bug, not a style.
|
|
75
|
+
- Everyday settings contain no compatibility notes, migration history, package
|
|
76
|
+
ownership or implementation terminology. Keep actionable loading, read-only,
|
|
77
|
+
conflict and reload feedback next to the affected controls.
|
|
68
78
|
- Use sections, not card grids. Cards are reserved for selectable strategy
|
|
69
79
|
cards, read-only budget panels, conversation cards and overlays.
|
|
70
|
-
- Save footer:
|
|
80
|
+
- Save footer: normal flow at the end, 1px top line, canvas background, 12px padding; only
|
|
71
81
|
visible while dirty, busy or showing a notice. Status left, actions right.
|
|
72
82
|
|
|
83
|
+
### Editable compaction process
|
|
84
|
+
|
|
85
|
+
- Use one bold visualization as the primary surface: a capacity bar with drag
|
|
86
|
+
handles, four strategy cards (native, goal-aware, handoff, custom), a compact
|
|
87
|
+
generation row, and a custom-prompt editor. Edit the existing configuration
|
|
88
|
+
draft through these controls; saving and discarding use the same form.
|
|
89
|
+
- The capacity bar supports pointer dragging and keyboard adjustment
|
|
90
|
+
(`role=slider`), with one synchronized numeric field per value. Do not repeat
|
|
91
|
+
the bar as full-width range sliders. If the model window is unknown, show a
|
|
92
|
+
proportional schematic and say so; never invent token totals.
|
|
93
|
+
- The four strategy cards are compact choices: title, tag and one-line effect,
|
|
94
|
+
no repeated mini-diagrams. On wide screens they sit in a two-column
|
|
95
|
+
**选择 | 示意图** layout: choices on the left, one shared SVG process drawing on
|
|
96
|
+
the right, capped at 400px so it fits beside the choices. It uses labeled
|
|
97
|
+
nodes and arrows for context, trigger, summary and continuation; it stacks
|
|
98
|
+
below the choices on narrow screens.
|
|
99
|
+
Selected state uses accent border + accent-soft + check; keyboard arrows,
|
|
100
|
+
Home/End and Space/Enter work.
|
|
101
|
+
- Custom mode is the fourth strategy: its expanded prompt is the only
|
|
102
|
+
instruction sent to the summary model. It appends no built-in structure,
|
|
103
|
+
state block or safety rules; the ten `{{variable}}` chips are the only
|
|
104
|
+
context injection. Entering custom mode with an empty prompt pre-fills the
|
|
105
|
+
**goal-mode default instruction** as an editable template; never overwrite an
|
|
106
|
+
existing prompt. Clearing the pre-filled text blocks saving; output must be
|
|
107
|
+
non-empty. Built-in modes never use the custom prompt.
|
|
108
|
+
- Capacity, reserved output and measured usage are observations. Unknown values
|
|
109
|
+
stay unknown; do not present active-engine estimates as a prediction of
|
|
110
|
+
unsaved settings.
|
|
111
|
+
- Keep only genuinely rare advanced policies and long read-only diagnostics
|
|
112
|
+
expandable. Behavior and effect settings are always visible.
|
|
113
|
+
|
|
73
114
|
### Narrow `<= 640px`
|
|
74
115
|
|
|
75
|
-
-
|
|
76
|
-
-
|
|
116
|
+
- Field rows stack: label above, control full width, touch targets 44px.
|
|
117
|
+
- Binary switches stay beside their labels, with a 44px hit area. Help buttons
|
|
118
|
+
are 44px, with descriptions contained inside the content column.
|
|
119
|
+
- Tables become cards. Read-only diagrams may become value rows. The editable
|
|
120
|
+
compaction process reflows into connected vertical stages and keeps its controls
|
|
121
|
+
available; never shrink the entire diagram into unreadable labels.
|
|
77
122
|
- No horizontal scrolling at 390px.
|
|
78
123
|
|
|
79
124
|
## 3. Controls
|
|
80
125
|
|
|
81
126
|
| Control | Contract |
|
|
82
127
|
| --- | --- |
|
|
83
|
-
| Button | 32px; radius 8; 13/500; primary
|
|
128
|
+
| Button | 32px; radius 8; 13/500; primary host button fill/foreground, secondary 1px line-2, ghost transparent; hover line-1 fill; focus 2px accent ring offset 2; disabled .4; loading spinner 12px |
|
|
84
129
|
| Text input / textarea | 32px; radius 8; 1px line-2; raised background; focus accent border + ring; number inputs tabular, no native spinners |
|
|
85
130
|
| Combobox | trigger shaped like text input; menu overlay surface, 1px line-3, radius 10, 4px padding, shadow; option 30px, radius 6, selected accent-soft + accent-text + check; ArrowUp/Down, Home/End, Enter/Space, Escape, typeahead; flip above when short; no native select/datalist |
|
|
86
131
|
| Segmented | container 32px, sunken, 1px line-2, radius 8; item 28px radius 6; selected raised + 1px line + accent-text 500; Arrow keys/Home/End; used for tabs and exclusive modes |
|
|
87
|
-
| Switch | 34×20 track, 2px padding, 14px thumb; on
|
|
132
|
+
| Switch | 34×20 track, 2px padding, 14px thumb; on host button fill/foreground, off sunken + line-3; focus ring; disabled .4 |
|
|
88
133
|
| Range | 4px track, accent filled portion, 14px thumb with 2px accent ring; number readout tabular and 76px wide |
|
|
89
134
|
| Choice card | 1px line-2, radius 10, padding 12; selected 1px accent + accent-soft; title 13/500, one line of 12/ink-3, schematic 120–160px; radio semantics |
|
|
90
135
|
| Chip / badge | 20px high, 11px, 1px line, radius 999; status only; at most one emphasized badge per screen |
|
|
91
|
-
| Details | summary 28–32px, 6px chevron, Escape closes; only for advanced
|
|
136
|
+
| Details | summary 28–32px, 6px chevron, Escape closes; only for rare advanced fields and long read-only diagnostics; behavior settings never hide here |
|
|
92
137
|
| Dialog / overlay | 1px line-2, radius 12; focus trapped and returned; Escape closes; shadow only here |
|
|
93
138
|
|
|
94
139
|
Keyboard:
|
|
@@ -129,12 +174,14 @@ tests. Add classes instead. In particular:
|
|
|
129
174
|
- Subagent: `.bs-root`, `.bs-title h2`, `.bs-header`, `.bs-switch`,
|
|
130
175
|
`.bs-advanced`, `.bs-cellLabel`, `.bs-footer` first child `.bs-status`,
|
|
131
176
|
`.bs-feedback`, `.bs-overviewGlyph`, combobox roles/ids, CSS literals.
|
|
132
|
-
- Compact: `.dsh-bc-page`,
|
|
133
|
-
|
|
177
|
+
- Compact: `.dsh-bc-page`, four `data-mode` radios, `data-bc=capacity-bar`,
|
|
178
|
+
`[role=slider]` handles, `data-bc-section=capacity|strategy|generation|prompt`,
|
|
179
|
+
`data-bc=process-result`, custom-prompt textarea and variable buttons,
|
|
134
180
|
form names/ids.
|
|
135
|
-
- Goal: `.dbg-cfg`, `h3.dbg-title`, `.dbg-section`,
|
|
136
|
-
`.dbg-
|
|
137
|
-
|
|
181
|
+
- Goal: `.dbg-cfg`, `h3.dbg-title`, `.dbg-section`, implementation/round-mode
|
|
182
|
+
radio ids, `.dbg-runtime`, `.dbg-footer`, `.dbg-status`, dock/history ids.
|
|
183
|
+
Native parameters and round policy are visible; no behavior `dbg-advanced`
|
|
184
|
+
or `dbg-diagnostics` fold.
|
|
138
185
|
- Ask-user: `better-ask-user-*` ids, `data-settings-dirty/busy`,
|
|
139
186
|
`data-settings-save`, `data-question-wait`, exact labels/aria.
|
|
140
187
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-better-dsh",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Better DSH: a DSH plugin bundle that installs workflow skills, engineering presets, and five independent plugins (goal, subagent, compact, ask-user, ptc). Pure ESM, no build step.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@deepseek-ai/schemastery": "~3.19.0",
|
|
61
|
-
"@oh-my-dsh/dsh-better-subagent": "0.5.
|
|
62
|
-
"dsh-better-ask-user": "0.3.
|
|
63
|
-
"dsh-better-compact": "0.
|
|
64
|
-
"dsh-better-goal": "0.4.
|
|
61
|
+
"@oh-my-dsh/dsh-better-subagent": "0.5.1",
|
|
62
|
+
"dsh-better-ask-user": "0.3.2",
|
|
63
|
+
"dsh-better-compact": "0.4.0",
|
|
64
|
+
"dsh-better-goal": "0.4.2",
|
|
65
65
|
"dsh-better-ptc": "0.2.0"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
@@ -9,6 +9,8 @@ Turn a large requirement into one approved master Spec and at least two executab
|
|
|
9
9
|
|
|
10
10
|
**The end state is a handoff to `/exec`.** Do not implement features, create worktrees, or invoke development skills. Stop once the user approves the written Specs.
|
|
11
11
|
|
|
12
|
+
Only the top-level main agent serving the user may dispatch review or re-review nodes. Subagents do their assigned work directly and return drafts, findings, or review requests to the main agent; they never dispatch reviewers, even if another skill calls for it.
|
|
13
|
+
|
|
12
14
|
## Process
|
|
13
15
|
|
|
14
16
|
1. **Explore project context** — inspect files, docs, and current project state. Look up facts yourself; do not ask the user.
|
|
@@ -16,7 +18,7 @@ Turn a large requirement into one approved master Spec and at least two executab
|
|
|
16
18
|
3. **Offer 2-3 options** — with tradeoffs and a recommendation, leading with the recommended option.
|
|
17
19
|
4. **Present the design in sections** — scale each section's length to its complexity, and get the user's confirmation on each. When a split is needed, present it (master Spec + sub-Specs, dependency order, shared contracts, integration acceptance).
|
|
18
20
|
5. **Write all Specs** — self-review after writing (placeholders, contradictions, ambiguity, over-detail) and fix inline. See self-review below.
|
|
19
|
-
6. **
|
|
21
|
+
6. **Main agent dispatches a spec-reviewer** — per [`spec-document-reviewer-prompt.md`](spec-document-reviewer-prompt.md), dispatch a fresh read-only `subagent` (quality tier) to review the master Spec and all sub-Specs; fix blockers and re-dispatch if needed.
|
|
20
22
|
7. **Ask the user to review** — revise per feedback until approved.
|
|
21
23
|
8. **Hand off to `/exec`** — tell the user to invoke `/exec` with the master Spec path.
|
|
22
24
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Spec Document Reviewer Prompt Template
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Only the top-level main agent serving the user uses this template to dispatch a spec document reviewer via the `subagent` tool (fresh read-only child, quality tier). Subagents return review requests to the main agent instead of dispatching reviewers.
|
|
4
4
|
|
|
5
5
|
**Purpose:** Verify a master Spec or sub-Spec is complete, consistent, and ready for implementation.
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ Use this template when dispatching a spec document reviewer via the `subagent` t
|
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
subagent(
|
|
11
|
-
prompt="You are a spec document reviewer. Verify this spec is complete and ready for implementation.
|
|
11
|
+
prompt="You are a spec document reviewer. Verify this spec is complete and ready for implementation. Perform the review directly; do not dispatch review nodes, even if another skill calls for it. Return findings and any further review needs to the main agent.
|
|
12
12
|
|
|
13
13
|
**Spec to review:** [SPEC_FILE_PATH]
|
|
14
14
|
**Spec type:** [master | sub]
|
|
@@ -10,7 +10,7 @@ Two-axis review of the diff between `HEAD` and a fixed point the user supplies:
|
|
|
10
10
|
- **Standards** — does the code conform to this repo's documented coding standards?
|
|
11
11
|
- **Spec** — does the code faithfully implement the originating issue / PRD / spec?
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Only the top-level main agent serving the user may dispatch review or re-review nodes. It dispatches both axes as parallel `subagent` delegations and aggregates their findings. If you are a subagent, perform only your assigned review directly and return findings or further review needs to the main agent; never dispatch reviewers, even if another skill calls for it.
|
|
14
14
|
|
|
15
15
|
## Process
|
|
16
16
|
|
|
@@ -57,7 +57,7 @@ Each smell reads *what it is* → *how to fix*; match it against the diff:
|
|
|
57
57
|
|
|
58
58
|
### 4. Spawn both sub-agents in parallel
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
The top-level main agent sends both `subagent` calls in a single message — each a fresh quality-tier child with a fully self-contained prompt; children see none of this conversation. Include in both prompts: "Perform this review directly. Do not dispatch review nodes; return findings and any further review needs to the main agent."
|
|
61
61
|
|
|
62
62
|
**Standards sub-agent prompt** — include:
|
|
63
63
|
|
package/skills/dev/SKILL.md
CHANGED
|
@@ -5,11 +5,13 @@ description: "Node contract for the DSH execution backend: prompt requirements,
|
|
|
5
5
|
|
|
6
6
|
# Built-in development backend (node contracts)
|
|
7
7
|
|
|
8
|
-
This skill defines the execution backend's two node types. Wave orchestration (worktrees, merging, cleanup, review-loop scheduling) belongs to `/exec`; this skill must not create, merge, or delete worktrees. Subagents have no independent working directory and cannot see the orchestration session: every node input must come with the prompt (absolute worktree path, Spec path, shared contracts, verification commands), with bash always using `workdir` and file tools always using absolute paths.
|
|
8
|
+
This skill defines the execution backend's two node types. Wave orchestration (worktrees, merging, cleanup, review-loop scheduling) belongs to `/exec`; this skill must not create, merge, or delete worktrees. Subagents have no independent working directory and cannot see the orchestration session: every node input must come with the prompt (absolute worktree path, Spec path, shared contracts, verification commands; implementation/fix nodes also need the execution mode and assigned tier), with bash always using `workdir` and file tools always using absolute paths.
|
|
9
|
+
|
|
10
|
+
Only the top-level main agent serving the user may dispatch review or re-review nodes. All subagents, including implementation/fix nodes and reviewers, perform their assigned work directly and return findings or review requests to the main agent. Never dispatch reviewers from a subagent, even when another skill calls for it.
|
|
9
11
|
|
|
10
12
|
## Implementation node (develop)
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
An implementation subagent handles exactly one sub-Spec at the caller-selected tier, following `main-agent-driven-development` in prebuilt-worktree mode. In `/exec`, skip its internal review step: the top-level main agent decides whether and when to request a sub-Spec review. Carry the execution mode into any further implementation/fix delegations. Fixes normally reuse the active node; `/exec` may hand off a node after it has stopped writing, either to escalate fast to quality in Automatic mode or to honor a later explicit mode change. Never run two implementation nodes writing to the same Spec at once.
|
|
13
15
|
|
|
14
16
|
Report format (JSON code block at the end of the closing message):
|
|
15
17
|
|
|
@@ -25,7 +27,7 @@ Report format (JSON code block at the end of the closing message):
|
|
|
25
27
|
|
|
26
28
|
## Review node (review-only)
|
|
27
29
|
|
|
28
|
-
A brand-new read-only subagent (quality tier). The prompt supplies: absolute worktree path, diff range, Spec path, implementation summary, and verification already run. Four-state verdict format (JSON code block at the end of the closing message):
|
|
30
|
+
A brand-new read-only subagent (quality tier), dispatched only by the top-level main agent. The reviewer performs the review directly and never delegates another review. The prompt supplies: absolute worktree path, diff range, Spec path, implementation summary, and verification already run. Four-state verdict format (JSON code block at the end of the closing message):
|
|
29
31
|
|
|
30
32
|
```js
|
|
31
33
|
{
|
|
@@ -38,4 +40,4 @@ Serious correctness errors, Spec gaps, integration risks, security issues, or mi
|
|
|
38
40
|
|
|
39
41
|
## Failure semantics
|
|
40
42
|
|
|
41
|
-
A subagent failure (error / empty return) = `node-failed`; `blocked`, timeouts, partial replies, or uncommitted results never count as complete. The caller decides whether to redispatch, or to continue via `send_message` only when unblocking the same sub-Spec. Never reuse a node for another sub-Spec.
|
|
43
|
+
A subagent failure (error / empty return) = `node-failed`; `blocked`, node execution timeouts, partial replies, or uncommitted results never count as complete. A `wait_subagent` timeout while the child is still running is not a node failure: wait again with `timeout_ms: 1800000` or longer, without status nudges or replacement merely because time elapsed. The caller decides whether to redispatch, or to continue via `send_message` only when unblocking the same sub-Spec. Never reuse a node for another sub-Spec.
|
package/skills/exec/SKILL.md
CHANGED
|
@@ -11,7 +11,21 @@ Run approved sub-Specs in isolated worktrees under `.worktrees/` in the target r
|
|
|
11
11
|
|
|
12
12
|
- The master Spec indexes at least two sub-Specs.
|
|
13
13
|
- Confirm a single target repo; the main workspace is on a named branch and its working tree is clean.
|
|
14
|
-
- `.worktrees/` is covered by the target repo's `.gitignore`; if
|
|
14
|
+
- Ensure `.worktrees/` is covered by the target repo's `.gitignore`; if missing, add the rule yourself and commit the setup change before creating wave worktrees.
|
|
15
|
+
|
|
16
|
+
## Execution mode
|
|
17
|
+
|
|
18
|
+
Before dispatching the first node, use `ask_user_question` to ask for the execution mode, unless the user already specified it for this run. The choice applies to implementation and fixes; **all code reviews use the quality tier**. Offer:
|
|
19
|
+
|
|
20
|
+
1. **Automatic (Recommended)** — use the fast tier by default; reserve the quality tier for particularly difficult tasks.
|
|
21
|
+
2. **Quality only** — use the quality tier for every implementation and fix.
|
|
22
|
+
3. **Fast only** — use the fast tier for every implementation and fix, without automatic escalation.
|
|
23
|
+
|
|
24
|
+
Default to Automatic if the question times out or the user skips the choice; use the host's normal question waiting behavior. A later explicit answer applies to future implementation/fix turns; let running turns finish. If the next fix requires a different tier, use the stopped-node handoff below instead of resuming the old route.
|
|
25
|
+
|
|
26
|
+
Keep the mode in session context and pass it to implementation/fix nodes and any further implementation delegations. In Automatic, ordinary implementation and routine fixes use fast; use quality only when the task demands unusually difficult reasoning or evidence shows the fast node cannot converge. Implementation work alone is not a reason to choose quality.
|
|
27
|
+
|
|
28
|
+
Resolve fast/quality from the current system prompt's configured routes and pass their `provider` / `model` / `reasoning_effort` to `subagent`; do not hardcode model IDs or use `subagent_fork` to select a tier. If a tier is unconfigured, follow its documented parent-route inheritance and disclose that distinct tiers are not configured. If a selected route is unavailable, report the blocker rather than silently switching tiers.
|
|
15
29
|
|
|
16
30
|
## Execution
|
|
17
31
|
|
|
@@ -21,58 +35,65 @@ Run approved sub-Specs in isolated worktrees under `.worktrees/` in the target r
|
|
|
21
35
|
|
|
22
36
|
## Wave execution: subagent + wait_subagent
|
|
23
37
|
|
|
24
|
-
The main agent orchestrates each wave; node contracts (prompt elements, report format, failure semantics) are in the `dev` skill.
|
|
38
|
+
The main agent orchestrates each wave; node contracts (prompt elements, report format, failure semantics) are in the `dev` skill. Only the top-level main agent serving the user may dispatch any review or re-review node. All subagents, including reviewers, must do their assigned work directly and return findings or review requests to the main agent; they never dispatch reviewers, even if another skill instructs them to.
|
|
25
39
|
|
|
26
|
-
1. **Dispatch**: in a single message, call `subagent` once per sub-Spec in this wave
|
|
40
|
+
1. **Dispatch**: in a single message, call `subagent` once per sub-Spec in this wave using the execution mode, and record "Spec → active subagent id and tier". Implementation-node prompt template:
|
|
27
41
|
|
|
28
42
|
```
|
|
29
43
|
You work in the isolated worktree <worktree absolute path>: always run bash with workdir=<worktree>, and use absolute paths for file tools.
|
|
30
|
-
|
|
44
|
+
Execution mode: <Automatic / Quality only / Fast only>; assigned tier: <fast / quality>. Carry the mode into any implementation/fix delegations.
|
|
45
|
+
Follow the main-agent-driven-development skill in prebuilt-worktree mode (skip its internal review step; the top-level main agent decides whether and when to request a sub-Spec review). Do not dispatch review nodes; report any review needs to the main agent.
|
|
31
46
|
Implement only <sub-Spec path> and obey the shared contracts: <contracts>. Run verification: <verification command>.
|
|
32
47
|
After committing, report in the dev skill's implementation-node format. Do not merge or delete the worktree; if blocked, set status=blocked and fill in blocker.
|
|
33
48
|
```
|
|
34
49
|
|
|
35
50
|
2. **Collect**: pass every id in this wave to `wait_subagent` in one call; reports arrive with the settlement notice. A Spec with a missing report, `blocked`, or no commit is recorded as `node-failed` and does not affect the other Specs in the wave.
|
|
36
|
-
3. **
|
|
37
|
-
- Dispatch a brand-new read-only reviewer (quality tier): `Read-only review of the full diff of worktree <worktree> against the baseline (always run bash with workdir=<worktree>). Spec: <path>. Implementation summary: <summary>. Verification already run: <verification>. List issues by severity, each with file and line number; judge with the dev skill's four-state format. Do not edit, commit, or merge.`
|
|
38
|
-
- `CHANGES_REQUIRED` → send the findings to the
|
|
51
|
+
3. **Choose sub-Spec reviews**: the orchestrator decides whether and when each completed Spec needs an independent code review, based on complexity, shared-contract impact, risk, and verification evidence. Ordinary low-risk changes can rely on the mandatory final integrated review. Briefly record the decision and reason in session context. For a selected review:
|
|
52
|
+
- Dispatch a brand-new read-only reviewer (quality tier): `Read-only review of the full diff of worktree <worktree> against the baseline (always run bash with workdir=<worktree>). Spec: <path>. Implementation summary: <summary>. Verification already run: <verification>. List issues by severity, each with file and line number; judge with the dev skill's four-state format. Perform the review directly; do not dispatch reviewers. Do not edit, commit, or merge.`
|
|
53
|
+
- `CHANGES_REQUIRED` → send the findings to the active implementation subagent with `send_message` (preserving its context), and require it to fix each real issue, explain false positives, rerun verification, commit, and report again; then wait and dispatch a brand-new quality reviewer. Apply the execution mode and escalation rules to fixes.
|
|
39
54
|
- At most 5 rounds; if still failing, record `review-exhausted`.
|
|
40
|
-
4.
|
|
55
|
+
4. **Merge eligibility**: committed, verified, in-scope Specs may proceed without a separate sub-Spec review when the orchestrator chose to omit it. A selected review must reach `APPROVED` / `APPROVED_WITH_NOTES`; never bypass required findings or a `BLOCKED` / exhausted review by changing the review decision.
|
|
41
56
|
|
|
42
57
|
Key points:
|
|
43
58
|
|
|
44
|
-
- Every review round uses a brand-new subagent; fixes reuse the
|
|
59
|
+
- Every review round uses a brand-new quality subagent; fixes normally reuse the active implementation subagent.
|
|
45
60
|
- Report any node question as blocked for the main agent to handle; do not ask the user within a wave.
|
|
46
61
|
- In PTC mode, a whole wave's dispatch and collection can be done in one `run_code`.
|
|
47
62
|
|
|
63
|
+
## Waiting and escalation
|
|
64
|
+
|
|
65
|
+
For every implementation, review, fix, and handoff wait in this workflow, call `wait_subagent` with all needed ids and `timeout_ms: 1800000` (30 minutes) or longer. Early completion returns immediately. Do independent work first; when blocked on results, wait patiently. If a wait expires while a node is still running, wait again with the same long window or continue independent work. A wait timeout is not a node failure or evidence that the task is particularly difficult. Do not send status nudges, repeatedly poll agent lists, or interrupt/replace a normally running node because it is taking time.
|
|
66
|
+
|
|
67
|
+
In Automatic only, an actual blocker, repeated failed attempts, or evidence of exceptional difficulty can justify a fast-to-quality handoff. A later explicit mode change can also require a handoff for the next implementation/fix turn. Reuse the existing node otherwise. Confirm the old node has stopped writing before dispatching its replacement; if interruption is needed, request it and wait for the node to stop. Inspect the actual worktree state and hand off the Spec, contracts, existing commits, any uncommitted changes, verification results, and unresolved issues to a new implementation node in the same worktree at the required tier (quality for automatic escalation). Update the active-node mapping; only one implementation node may write to a Spec at a time. After escalation, keep that quality node for subsequent fixes unless the user explicitly changes the mode.
|
|
68
|
+
|
|
48
69
|
## Merge
|
|
49
70
|
|
|
50
|
-
For each
|
|
71
|
+
For each eligible node: confirm it is committed and verification passed → check the changed files for out-of-scope edits → merge into the main workspace → verify after merging → delete the worktree and sub-branch.
|
|
51
72
|
|
|
52
|
-
|
|
73
|
+
Resolve conflicts through an implementation/fix node under the execution mode; use a new fix worktree under `.worktrees/` for complex conflicts. Never merge failed or blocked nodes.
|
|
53
74
|
|
|
54
75
|
## Final review
|
|
55
76
|
|
|
56
|
-
Once all sub-Specs are merged, run the full integration verification, then dispatch a brand-new read-only reviewer subagent (quality tier) to review the whole integrated result:
|
|
77
|
+
Once all sub-Specs are merged, run the full integration verification, then always dispatch a brand-new read-only reviewer subagent (quality tier) to review the whole integrated result, even when sub-Spec reviews were omitted:
|
|
57
78
|
|
|
58
79
|
```
|
|
59
80
|
subagent(
|
|
60
81
|
prompt="Read-only review of the <base>..HEAD diff in <workspace> (always run bash with workdir=<workspace>).
|
|
61
82
|
Master Spec: <path> | all sub-Specs | shared contracts | changed files | implementation summary | verification results.
|
|
62
83
|
List issues by severity, each with file and line number.
|
|
63
|
-
Return APPROVED / APPROVED_WITH_NOTES / CHANGES_REQUIRED / BLOCKED. Do not edit, commit, or merge."
|
|
84
|
+
Return APPROVED / APPROVED_WITH_NOTES / CHANGES_REQUIRED / BLOCKED. Perform the review directly; do not dispatch reviewers. Do not edit, commit, or merge."
|
|
64
85
|
)
|
|
65
86
|
```
|
|
66
87
|
|
|
67
|
-
Wait
|
|
88
|
+
Wait using the long window above. On `CHANGES_REQUIRED` there is no need to ask the user — the main agent classifies findings and briefly explains false positives and existing behavior in context. Delegate real fixes to an implementation/fix node in an isolated worktree under the execution mode, integrate the committed fixes, verify again, and dispatch a brand-new quality reviewer for re-review. If serious or blocking issues remain after a soft cap of 3 rounds, stop the fix loop and truthfully report the remaining issues to the user. A blocked review is not approval.
|
|
68
89
|
|
|
69
90
|
## Wrap-up
|
|
70
91
|
|
|
71
|
-
Run the full verification, check the Specs, report branches, commits, verification results, and open issues, and ask the user what to do next. Do not create a PR or delete branches without the user's choice.
|
|
92
|
+
Run the full verification, check the Specs, report the execution mode, actual tier use and escalations, sub-Spec review decisions, branches, commits, verification results, and open issues, and ask the user what to do next. Do not create a PR or delete branches without the user's choice.
|
|
72
93
|
|
|
73
94
|
## KISS
|
|
74
95
|
|
|
75
|
-
- One sub-Spec, one worktree, one
|
|
76
|
-
- The main agent holds repo topology (branches/worktrees/merges/cleanup) and
|
|
96
|
+
- One sub-Spec, one worktree, at most one active implementation node.
|
|
97
|
+
- The main agent holds repo topology (branches/worktrees/merges/cleanup) and scheduling; implementation, fixes, and selected reviews go to subagents.
|
|
77
98
|
- State lives only in session context; add no integration branch, scheduler scripts, or state files.
|
|
78
99
|
- Completion notices arrive automatically; wait only when you need results to proceed. Never poll with `sleep`.
|
|
@@ -14,7 +14,7 @@ Choose exactly one:
|
|
|
14
14
|
- **Prebuilt mode** — when the caller already provided an isolated worktree and owns its lifecycle, use it directly; do not create, merge, or delete worktrees.
|
|
15
15
|
- **Standalone mode** — otherwise, identify the target repo, require the baseline to be on a named branch, record the starting SHA, and create a worktree under the repo's `.worktrees/`.
|
|
16
16
|
|
|
17
|
-
All operations must happen inside the chosen worktree. After isolation, do not edit the original checkout.
|
|
17
|
+
All operations must happen inside the chosen worktree. After isolation, do not edit the original checkout. When called by `/exec`, follow the assigned execution mode and tier, including in any further implementation/fix delegations; report blockers to the orchestrator rather than changing your own tier.
|
|
18
18
|
|
|
19
19
|
## Flow
|
|
20
20
|
|
|
@@ -26,14 +26,16 @@ All operations must happen inside the chosen worktree. After isolation, do not e
|
|
|
26
26
|
6. After each logical step, run focused verification, self-review the diff, and commit when it is complete. Verification standard: run the command this round and confirm the output; never replace it with "it should pass".
|
|
27
27
|
7. After implementation, run all required verification.
|
|
28
28
|
8. When verification fails or review finds a bug, follow the `diagnosing-bugs` skill (bundled in this package): build a feedback loop to find the root cause first, then fix.
|
|
29
|
-
9.
|
|
29
|
+
9. Only the top-level main agent serving the user runs the internal review loop (see below). When acting as any implementation/fix subagent, **skip this step** — return the implementation and any review needs to the main agent, which owns all review dispatch.
|
|
30
30
|
10. Commit all approved fixes and report to the caller.
|
|
31
31
|
|
|
32
32
|
Keep it KISS. Prefer reusing existing patterns, small and complete changes, and only the targeted refactoring the Spec requires.
|
|
33
33
|
|
|
34
34
|
## Internal review loop
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Only the top-level main agent may dispatch review or re-review nodes. Subagents never dispatch reviewers, even if invoked outside `/exec` or another skill calls for review.
|
|
37
|
+
|
|
38
|
+
After full verification, the main agent dispatches exactly one brand-new read-only reviewer subagent (quality tier):
|
|
37
39
|
|
|
38
40
|
```
|
|
39
41
|
subagent(
|
|
@@ -41,13 +43,14 @@ subagent(
|
|
|
41
43
|
Spec: <path>
|
|
42
44
|
Implementation summary: <brief>
|
|
43
45
|
Changed files: <list>
|
|
44
|
-
Verification already run: <commands and results>
|
|
46
|
+
Verification already run: <commands and results>
|
|
47
|
+
Perform the review directly; do not dispatch review nodes. Return any further review needs to the main agent."
|
|
45
48
|
)
|
|
46
49
|
```
|
|
47
50
|
|
|
48
51
|
Require file and line numbers, and one status: `APPROVED` / `APPROVED_WITH_NOTES` / `CHANGES_REQUIRED` / `BLOCKED`.
|
|
49
52
|
|
|
50
|
-
Wait for the review with `wait_subagent
|
|
53
|
+
Wait for the review with `wait_subagent` and `timeout_ms: 1800000` (30 minutes) or longer; early completion returns immediately. If the reviewer is still running after a wait timeout, continue long waits without status nudges or replacing it merely because time elapsed. Once results arrive, fix all necessary correctness errors, Spec gaps, security issues, integration risks, and verification gaps directly — no need to ask the user. After verifying and committing the fixes, dispatch a brand-new reviewer with `subagent` again. Repeat until `APPROVED` or only non-blocking suggestions remain.
|
|
51
54
|
|
|
52
55
|
Never self-approve, and never reuse an old reviewer.
|
|
53
56
|
|
|
@@ -58,7 +61,7 @@ Before reporting completion, all of the following must hold:
|
|
|
58
61
|
- All assigned acceptance criteria are implemented
|
|
59
62
|
- Required verification ran and passed this round (backed by command output)
|
|
60
63
|
- No uncommitted implementation changes
|
|
61
|
-
- Internal review passed with no required fixes
|
|
64
|
+
- Internal review passed with no required fixes, except for implementation/fix subagents whose review scheduling belongs to the top-level main agent
|
|
62
65
|
- The final commit SHA is available
|
|
63
66
|
|
|
64
67
|
Report blockers truthfully. Do not merge on your own; the caller owns integration and cleanup.
|
package/src/client.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* `t` 用 `ctx.locale.bind(entry.locale)` 补齐。子插件页面永远是单一事实
|
|
16
16
|
* 源,本文件不复制任何字段定义。
|
|
17
17
|
*
|
|
18
|
-
*
|
|
18
|
+
* 主题:选择、按钮、表面与文字均映射宿主 --dsw-alias-* 令牌。
|
|
19
19
|
* 零构建:closure factory,只 require('react') + 可选 ui-primitives(Modal
|
|
20
20
|
* 兜底为自绘 overlay);不 fetch、不直接写 DOM。
|
|
21
21
|
*/
|
|
@@ -58,40 +58,35 @@ window.__ModuleLoader__.load({
|
|
|
58
58
|
];
|
|
59
59
|
|
|
60
60
|
const zh = {
|
|
61
|
-
summary: '
|
|
61
|
+
summary: '后台任务与远程访问设置',
|
|
62
62
|
title: '通用',
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
purpose: '控制助手在后台任务运行时如何收尾,以及是否允许受信任的反向代理修改设置。',
|
|
64
|
+
connectionTitle: '远程访问',
|
|
65
|
+
guardTitle: '后台任务',
|
|
66
|
+
ownsHostLabel: '允许通过反向代理修改设置',
|
|
66
67
|
ownsHostHint: '仅在你控制访问权限的可信反向代理后启用。这会允许该页面写入宿主设置;不改变子代理 API 的可信地址列表。',
|
|
67
68
|
ownsHostReload: '保存后需重载 profile 并刷新页面。',
|
|
68
69
|
savedReload: '已保存;重载 profile 并刷新页面后生效。',
|
|
69
|
-
guardEnd: '回合结束',
|
|
70
|
-
guardJobs: '后台任务',
|
|
71
|
-
guardContinue: '有任务则继续',
|
|
72
|
-
guardAllow: '允许结束',
|
|
73
|
-
compatTitle: '兼容性',
|
|
74
|
-
migratedBody: 'CLI 子代理、wait_subagent、运行中子代理守卫、模型分档与子代理设置页由 @oh-my-dsh/dsh-better-subagent 拥有;压缩模式与预算由 dsh-better-compact 拥有。请到 Plugins 中对应的行配置,或使用包详情页的集成设置弹窗。',
|
|
75
|
-
deprecatedBody: '旧 Apollo 行里的 tiers / subagents / trustedHosts 只为迁移旧 profile 保留,运行时不再生效;迁移在启动后自动补齐新插件的缺失值,目标行已有显式设置时不会被覆盖。',
|
|
76
|
-
reloadBody: '从 0.4.x 升级、或同时显式选中了独立 bundle 时,行可能显示为只读/不可寻址;请只保留一个显式入口并重载 profile。压缩设置的保存需要重载 profile 才会被引擎采用。',
|
|
77
70
|
loading: '正在读取配置…',
|
|
78
|
-
waitingForm: '
|
|
79
|
-
noFormHint: '
|
|
80
|
-
unavailable: '
|
|
81
|
-
readonly: '
|
|
82
|
-
exitGuardLabel: '
|
|
71
|
+
waitingForm: '正在读取设置…',
|
|
72
|
+
noFormHint: '暂时无法读取设置。请重新连接后再试。',
|
|
73
|
+
unavailable: '当前地址无法修改设置。请使用本机地址打开,或在服务器上允许此地址访问设置。',
|
|
74
|
+
readonly: '当前连接仅支持查看设置。',
|
|
75
|
+
exitGuardLabel: '等待后台任务完成',
|
|
76
|
+
exitGuardDescription: '后台命令尚未结束时,让助手继续跟进。',
|
|
77
|
+
ownsHostDescription: '仅对你控制访问权限的反向代理开启;保存后需重载。',
|
|
83
78
|
exitGuardHint: '回合结束时仍有运行中的后台命令会注入提醒强制继续处理;Esc 中断始终放行。',
|
|
84
79
|
save: '保存',
|
|
85
80
|
saving: '保存中…',
|
|
86
81
|
reset: '放弃改动',
|
|
87
82
|
saved: '已保存,即时生效。',
|
|
88
|
-
conflict: '
|
|
83
|
+
conflict: '设置已在其他地方更新。已重新读取最新值,请检查后重试。',
|
|
89
84
|
saveFailed: '保存失败:',
|
|
90
85
|
readonlyNote: '只读:当前无法写入宿主配置。',
|
|
91
86
|
unavailableNote: '不可写:当前连接下该配置不可用。',
|
|
92
87
|
hubButton: '集成设置',
|
|
93
88
|
hubTitle: 'Better DSH',
|
|
94
|
-
hubEmpty: '
|
|
89
|
+
hubEmpty: '暂无可用的设置页。请检查插件是否已启用。',
|
|
95
90
|
close: '关闭',
|
|
96
91
|
unsavedTitle: '有未保存的改动',
|
|
97
92
|
unsavedBody: '关闭将放弃各页面尚未保存的设置。',
|
|
@@ -99,48 +94,43 @@ window.__ModuleLoader__.load({
|
|
|
99
94
|
discardClose: '放弃并关闭',
|
|
100
95
|
entryError: '此设置区加载失败:',
|
|
101
96
|
retry: '重新加载',
|
|
102
|
-
pluginBetterDsh: '
|
|
97
|
+
pluginBetterDsh: '通用',
|
|
103
98
|
pluginSubagent: '子代理',
|
|
104
99
|
pluginCompact: '上下文压缩',
|
|
105
|
-
pluginGoal: '
|
|
100
|
+
pluginGoal: '目标与续跑',
|
|
106
101
|
pluginAskUser: '提问',
|
|
107
102
|
};
|
|
108
103
|
|
|
109
104
|
const en = {
|
|
110
|
-
summary: 'Background
|
|
105
|
+
summary: 'Background work and remote access settings',
|
|
111
106
|
title: 'General',
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
purpose: 'Control how the assistant finishes while background work runs, and whether a trusted reverse proxy may change settings.',
|
|
108
|
+
connectionTitle: 'Remote access',
|
|
109
|
+
guardTitle: 'Background work',
|
|
110
|
+
ownsHostLabel: 'Allow settings changes through a reverse proxy',
|
|
115
111
|
ownsHostHint: 'Enable only behind a trusted proxy whose access you control. This allows the page to write host settings; it does not change the subagent API’s trusted authorities.',
|
|
116
112
|
ownsHostReload: 'Save, then reload the profile and refresh the page.',
|
|
117
113
|
savedReload: 'Saved. Reload the profile and refresh the page to apply.',
|
|
118
|
-
guardEnd: 'Turn ends',
|
|
119
|
-
guardJobs: 'Background jobs',
|
|
120
|
-
guardContinue: 'Continue if running',
|
|
121
|
-
guardAllow: 'Allow completion',
|
|
122
|
-
compatTitle: 'Compatibility',
|
|
123
|
-
migratedBody: 'CLI subagents, wait_subagent, the running-child guard, model tiers and the subagent settings page are owned by @oh-my-dsh/dsh-better-subagent; compaction modes and budgets are owned by dsh-better-compact. Configure their rows under Plugins, or use the integrated settings dialog on the package page.',
|
|
124
|
-
deprecatedBody: 'The old Apollo tiers / subagents / trustedHosts fields are kept only so 0.4.x profiles load; they are inert at runtime. After boot the migration fills the new plugins’ missing values and never overwrites an explicit target setting.',
|
|
125
|
-
reloadBody: 'Upgrading from 0.4.x, or selecting both the standalone and Apollo bundles explicitly, can make the row read-only/unaddressable: keep a single explicit entry and reload the profile. Saved compaction settings take effect only after the profile reloads.',
|
|
126
114
|
loading: 'Loading configuration…',
|
|
127
|
-
waitingForm: '
|
|
128
|
-
noFormHint: '
|
|
129
|
-
unavailable: '
|
|
130
|
-
readonly: '
|
|
115
|
+
waitingForm: 'Loading settings…',
|
|
116
|
+
noFormHint: 'Settings could not be loaded. Reconnect and try again.',
|
|
117
|
+
unavailable: 'Settings cannot be changed from this address. Open the local address or allow this address on the server.',
|
|
118
|
+
readonly: 'Settings can only be viewed on this connection.',
|
|
131
119
|
exitGuardLabel: 'Wait for background work',
|
|
120
|
+
exitGuardDescription: 'Keep the assistant working while background commands are still running.',
|
|
121
|
+
ownsHostDescription: 'Enable for a reverse proxy whose access you control. Reload after saving.',
|
|
132
122
|
exitGuardHint: 'Blocks turn end while background commands still run; Esc always passes through.',
|
|
133
123
|
save: 'Save',
|
|
134
124
|
saving: 'Saving…',
|
|
135
125
|
reset: 'Discard',
|
|
136
126
|
saved: 'Saved and applied.',
|
|
137
|
-
conflict: '
|
|
127
|
+
conflict: 'Settings changed elsewhere. The latest values have been loaded; review them and try again.',
|
|
138
128
|
saveFailed: 'Save failed: ',
|
|
139
129
|
readonlyNote: 'Read-only: host configuration cannot be written.',
|
|
140
130
|
unavailableNote: 'Not writable: this configuration is unavailable on the current connection.',
|
|
141
131
|
hubButton: 'Integrated settings',
|
|
142
132
|
hubTitle: 'Better DSH',
|
|
143
|
-
hubEmpty: 'No
|
|
133
|
+
hubEmpty: 'No settings pages are available. Check that the plugins are enabled.',
|
|
144
134
|
close: 'Close',
|
|
145
135
|
unsavedTitle: 'Unsaved changes',
|
|
146
136
|
unsavedBody: 'Closing discards unsaved settings on all pages.',
|
|
@@ -148,10 +138,10 @@ window.__ModuleLoader__.load({
|
|
|
148
138
|
discardClose: 'Discard and close',
|
|
149
139
|
entryError: 'This settings pane failed to load: ',
|
|
150
140
|
retry: 'Retry',
|
|
151
|
-
pluginBetterDsh: '
|
|
141
|
+
pluginBetterDsh: 'General',
|
|
152
142
|
pluginSubagent: 'Subagents',
|
|
153
143
|
pluginCompact: 'Compaction',
|
|
154
|
-
pluginGoal: 'Goals',
|
|
144
|
+
pluginGoal: 'Goals and continuation',
|
|
155
145
|
pluginAskUser: 'Questions',
|
|
156
146
|
};
|
|
157
147
|
|
|
@@ -165,9 +155,11 @@ window.__ModuleLoader__.load({
|
|
|
165
155
|
const STYLE_ID = 'dsh-better-dsh/settings.css';
|
|
166
156
|
const CSS = `
|
|
167
157
|
/* UI-KIT v1 — keep in sync with docs/UI-KIT.md. Flat surfaces, 1px lines, one accent. */
|
|
168
|
-
.apollo-cfg,.apollo-root,.apollo-hub,.apollo-modal,.apollo-modalCard,.apollo-button[data-apollo-hub=trigger]{--cfg-accent
|
|
169
|
-
[data-ds-dark-theme] :is(.apollo-cfg,.apollo-root,.apollo-hub,.apollo-modal,.apollo-modalCard,.apollo-button[data-apollo-hub=trigger]){--cfg-accent
|
|
170
|
-
.apollo-cfg{display:flex;flex-direction:column;gap:
|
|
158
|
+
.apollo-cfg,.apollo-root,.apollo-hub,.apollo-modal,.apollo-modalCard,.apollo-button[data-apollo-hub=trigger]{--cfg-accent:var(--dsw-alias-state-business-primary,#4176e6);--cfg-accent-solid:var(--dsw-alias-button-primary-fill,#0f1115);--cfg-accent-text:color-mix(in srgb,var(--cfg-accent) 70%,var(--dsw-alias-label-primary));--cfg-accent-fg:var(--dsw-alias-label-primary-foreground,#fff);--cfg-accent-soft:color-mix(in srgb,var(--cfg-accent) 10%,transparent);--cfg-accent-ink:color-mix(in srgb,var(--cfg-accent) 70%,var(--dsw-alias-label-primary));--cfg-surface:var(--dsw-alias-bg-layer-1);--cfg-raised:var(--dsw-alias-bg-layer-2);--cfg-overlay:var(--dsw-alias-bg-layer-3);--cfg-sunken:color-mix(in srgb,var(--dsw-alias-label-primary) 4%,var(--cfg-surface));--cfg-ink:var(--dsw-alias-label-primary);--cfg-ink-2:var(--dsw-alias-label-secondary);--cfg-ink-3:color-mix(in srgb,var(--dsw-alias-label-tertiary) 80%,var(--dsw-alias-label-primary));--cfg-border:var(--dsw-alias-border-l2,color-mix(in srgb,currentColor 14%,transparent));--cfg-border-strong:var(--dsw-alias-border-l3,color-mix(in srgb,currentColor 22%,transparent));--cfg-line:var(--dsw-alias-border-l1,color-mix(in srgb,currentColor 8%,transparent));--cfg-hover:var(--dsw-alias-interactive-bg-hover,color-mix(in srgb,currentColor 6%,transparent));--cfg-danger:color-mix(in srgb,var(--dsw-alias-state-error-primary) 60%,var(--dsw-alias-label-primary));--cfg-success:color-mix(in srgb,var(--dsw-alias-state-success-primary) 60%,var(--dsw-alias-label-primary));--cfg-warn:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 60%,var(--dsw-alias-label-primary));--cfg-mono:ui-monospace,SFMono-Regular,Menlo,monospace;--cfg-control:32px;--cfg-radius:8px;--cfg-dur:140ms;font-size:13px;line-height:20px;color:var(--cfg-ink);font-variant-numeric:tabular-nums}
|
|
159
|
+
[data-ds-dark-theme] :is(.apollo-cfg,.apollo-root,.apollo-hub,.apollo-modal,.apollo-modalCard,.apollo-button[data-apollo-hub=trigger]){--cfg-accent:var(--dsw-alias-state-business-primary,#a6c4ff);--cfg-accent-solid:var(--dsw-alias-button-primary-fill,#e4e4e9);--cfg-accent-text:color-mix(in srgb,var(--cfg-accent) 70%,var(--dsw-alias-label-primary));--cfg-accent-fg:var(--dsw-alias-label-primary-foreground,#000);--cfg-accent-soft:color-mix(in srgb,var(--cfg-accent) 14%,transparent);--cfg-accent-ink:var(--cfg-accent-text)}
|
|
160
|
+
.apollo-cfg{display:flex;flex-direction:column;gap:20px;max-width:960px;width:100%;margin:0 auto;min-width:0}
|
|
161
|
+
.apollo-pageTitleBlock{display:flex;flex-direction:column;gap:4px;min-width:0}
|
|
162
|
+
.apollo-pageSub{margin:0;color:var(--cfg-ink-3);font-size:13px;line-height:20px}
|
|
171
163
|
.apollo-pageHead{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}
|
|
172
164
|
.apollo-pageTitle{margin:0;font-size:20px;line-height:28px;font-weight:500;letter-spacing:-.01em;color:var(--cfg-ink)}
|
|
173
165
|
.apollo-badge{display:inline-flex;align-items:center;height:20px;padding:0 8px;border:1px solid var(--cfg-border);border-radius:999px;background:var(--cfg-raised);font-size:11px;line-height:18px;color:var(--cfg-ink-3);white-space:nowrap}
|
|
@@ -178,10 +170,11 @@ window.__ModuleLoader__.load({
|
|
|
178
170
|
@keyframes apollo-pulse{0%{opacity:1}40%{opacity:.6}80%,to{opacity:1}}
|
|
179
171
|
.apollo-hint{margin:0;font-size:12px;line-height:18px;color:var(--cfg-ink-3)}
|
|
180
172
|
.apollo-mono{font-family:var(--cfg-mono);font-variant-numeric:tabular-nums}
|
|
181
|
-
.apollo-card{display:flex;flex-direction:column;gap:
|
|
182
|
-
.apollo-sectionTitle{margin:0;font-size:12px;line-height:18px;font-weight:500;color:var(--cfg-ink-3)}
|
|
183
|
-
.apollo-row{display:flex;align-items:
|
|
184
|
-
.apollo-row:
|
|
173
|
+
.apollo-card{display:flex;flex-direction:column;gap:4px;min-width:0;padding:0;border:0;border-radius:0;background:transparent}
|
|
174
|
+
.apollo-sectionTitle{margin:0;padding-bottom:0;border-bottom:0;font-size:12px;line-height:18px;font-weight:500;color:var(--cfg-ink-3)}
|
|
175
|
+
.apollo-row{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:10px 8px;margin:0 -8px;min-width:0;border-bottom:0;border-radius:8px}
|
|
176
|
+
.apollo-row:hover{background:var(--cfg-hover)}
|
|
177
|
+
.apollo-row:last-child{padding-bottom:10px}
|
|
185
178
|
.apollo-rowText{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}
|
|
186
179
|
.apollo-rowTitle{font-size:13px;line-height:20px;font-weight:500;color:var(--cfg-ink);cursor:default}
|
|
187
180
|
.apollo-rowDesc{max-width:560px;font-size:12px;line-height:18px;color:var(--cfg-ink-3)}
|
|
@@ -192,18 +185,18 @@ window.__ModuleLoader__.load({
|
|
|
192
185
|
.apollo-help>button:focus-visible{outline:2px solid var(--cfg-accent);outline-offset:2px}
|
|
193
186
|
.apollo-help>p{position:absolute;left:0;top:26px;z-index:40;width:320px;max-width:min(320px,70vw);margin:0;padding:10px 12px;border:1px solid var(--cfg-border-strong);border-radius:8px;background:var(--cfg-overlay);color:var(--cfg-ink-2);font-size:12px;line-height:18px;font-weight:400;box-shadow:0 12px 32px -16px rgb(0 0 0/.45)}
|
|
194
187
|
.apollo-help>p[hidden]{display:none}
|
|
195
|
-
.apollo-switch{box-sizing:border-box;position:relative;flex:none;width:34px;height:20px;margin:1px 0 0;padding:2px;border:1px solid var(--cfg-border-strong);border-radius:999px;background:var(--cfg-sunken);cursor:pointer;appearance:none;transition:background var(--cfg-dur) ease,border-color var(--cfg-dur) ease}
|
|
188
|
+
.apollo-switch{box-sizing:border-box;position:relative;flex:none;width:34px;height:20px;margin:1px 5px 0 0;padding:2px;border:1px solid var(--cfg-border-strong);border-radius:999px;background:var(--cfg-sunken);cursor:pointer;appearance:none;transition:background var(--cfg-dur) ease,border-color var(--cfg-dur) ease}
|
|
196
189
|
.apollo-switch:hover:not(:disabled){border-color:var(--cfg-ink-3)}
|
|
197
|
-
.apollo-switch[aria-checked=true]{border-color:var(--cfg-accent);background:var(--cfg-accent-solid)}
|
|
190
|
+
.apollo-switch[aria-checked=true]{border-color:var(--cfg-accent-solid);background:var(--cfg-accent-solid)}
|
|
198
191
|
.apollo-switch:disabled{opacity:.4;cursor:not-allowed}
|
|
199
192
|
.apollo-switchThumb{display:block;width:14px;height:14px;border-radius:50%;background:var(--cfg-ink-3);transition:transform var(--cfg-dur) ease,background var(--cfg-dur) ease}
|
|
200
193
|
.apollo-switch[aria-checked=true] .apollo-switchThumb{transform:translateX(14px);background:var(--cfg-accent-fg)}
|
|
201
|
-
.apollo-switch:before{content:"";position:absolute;inset:-
|
|
194
|
+
.apollo-switch:before{content:"";position:absolute;inset:-12px -5px}
|
|
202
195
|
.apollo-switch:focus-visible{outline:2px solid var(--cfg-accent);outline-offset:2px}
|
|
203
196
|
.apollo-button{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border:1px solid transparent;border-radius:8px;font:inherit;font-size:13px;line-height:20px;font-weight:500;color:var(--cfg-ink);background:transparent;cursor:pointer;transition:background var(--cfg-dur) ease,border-color var(--cfg-dur) ease,color var(--cfg-dur) ease}
|
|
204
197
|
.apollo-button:disabled{opacity:.4;cursor:not-allowed}
|
|
205
198
|
.apollo-button[data-variant=primary]{background:var(--cfg-accent-solid);color:var(--cfg-accent-fg)}
|
|
206
|
-
.apollo-button[data-variant=primary]:hover:not(:disabled){background:color-mix(in srgb,var(--cfg-accent-solid) 88%,
|
|
199
|
+
.apollo-button[data-variant=primary]:hover:not(:disabled){background:color-mix(in srgb,var(--cfg-accent-solid) 88%,var(--cfg-accent-fg))}
|
|
207
200
|
.apollo-button[data-variant=outline]{border-color:var(--cfg-border-strong)}
|
|
208
201
|
.apollo-button[data-variant=outline]:hover:not(:disabled),.apollo-button[data-variant=ghost]:hover:not(:disabled){background:var(--cfg-hover)}
|
|
209
202
|
.apollo-button:focus-visible{outline:2px solid var(--cfg-accent);outline-offset:2px}
|
|
@@ -217,38 +210,23 @@ window.__ModuleLoader__.load({
|
|
|
217
210
|
.apollo-status[data-tone=ok]{color:var(--cfg-success)}
|
|
218
211
|
.apollo-status[data-tone=error]{color:var(--cfg-danger)}
|
|
219
212
|
.apollo-status[data-tone=warn]{color:var(--cfg-warn)}
|
|
220
|
-
.apollo-details{min-width:0;border-top:1px solid var(--cfg-border);padding:8px 0 0;font-size:13px;line-height:20px}
|
|
221
|
-
.apollo-details>summary{display:flex;align-items:center;gap:8px;list-style:none;cursor:pointer;min-height:32px;padding:4px 0;font-size:13px;line-height:20px;font-weight:500;color:var(--cfg-ink-2)}
|
|
222
|
-
.apollo-details>summary::-webkit-details-marker{display:none}
|
|
223
|
-
.apollo-details>summary:before{content:"";width:6px;height:6px;flex:none;border-right:1px solid currentColor;border-bottom:1px solid currentColor;transform:rotate(-45deg);transition:transform var(--cfg-dur) ease}
|
|
224
|
-
.apollo-details[open]>summary:before{transform:rotate(45deg)}
|
|
225
|
-
.apollo-details>summary:hover{color:var(--cfg-ink)}
|
|
226
|
-
.apollo-details>summary:focus-visible{outline:2px solid var(--cfg-accent);outline-offset:2px;border-radius:4px}
|
|
227
|
-
.apollo-detailsBody{display:flex;flex-direction:column;gap:10px;padding:6px 0 4px;color:var(--cfg-ink-2)}
|
|
228
|
-
.apollo-guardFlow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;margin:2px 0 0;padding:14px 12px;border:1px solid var(--cfg-border);border-radius:8px;background:var(--cfg-sunken)}
|
|
229
|
-
.apollo-flowStep{position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0;text-align:center;color:var(--cfg-ink-2)}
|
|
230
|
-
.apollo-flowStep svg{box-sizing:content-box;display:block;padding:6px;border:1px solid var(--cfg-border);border-radius:8px;background:var(--cfg-raised);color:var(--cfg-ink-2)}
|
|
231
|
-
.apollo-flowLabel{font-size:12px;line-height:18px;max-width:130px;overflow-wrap:normal;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
232
|
-
.apollo-flowStep:not(:last-child):after{content:"";position:absolute;left:calc(50% + 24px);top:15px;width:calc(100% - 40px);border-top:1px solid var(--cfg-border)}
|
|
233
|
-
.apollo-guardFlow[data-enabled=true] .apollo-flowStep:last-child{color:var(--cfg-accent-text)}
|
|
234
|
-
.apollo-guardFlow[data-enabled=true] .apollo-flowStep:last-child svg{border-color:color-mix(in srgb,var(--cfg-accent) 35%,var(--cfg-border));background:var(--cfg-accent-soft);color:var(--cfg-accent-text)}
|
|
235
213
|
.apollo-hubGlyph{flex:none;color:var(--cfg-ink-3)}
|
|
236
214
|
.apollo-closeConfirm{box-sizing:border-box;display:flex;flex-direction:column;justify-content:center;gap:16px;min-height:280px;width:100%;padding:32px}
|
|
237
215
|
.apollo-closeConfirm p{margin:0;color:var(--cfg-ink-2);font-size:13px;line-height:20px}
|
|
238
216
|
.apollo-closeActions{display:flex;justify-content:flex-end;gap:8px}
|
|
239
|
-
.apollo-modal.apollo-modal{width:min(1240px,calc(100vw - 32px));max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);padding-bottom:0;border:1px solid var(--cfg-border);border-radius:
|
|
217
|
+
.apollo-modal.apollo-modal{width:min(1240px,calc(100vw - 32px));max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);padding-bottom:0;border:1px solid var(--cfg-border);border-radius:10px}
|
|
240
218
|
.apollo-hubModalContent>:first-child{margin:0;padding:14px 20px;border-bottom:1px solid var(--cfg-border)}
|
|
241
219
|
.apollo-hubModalContent>:first-child h2{font-size:15px;line-height:22px;font-weight:500}
|
|
242
220
|
.apollo-hubModalContent>:last-child{margin:0;padding:0}
|
|
243
221
|
.apollo-hub{display:flex;gap:0;height:min(760px,calc(100dvh - 96px));min-height:320px;width:100%;overflow:hidden}
|
|
244
|
-
.apollo-hubNav{box-sizing:border-box;flex:none;width:
|
|
245
|
-
.apollo-hubNavItem{display:flex;align-items:center;gap:10px;flex-shrink:0;min-height:
|
|
222
|
+
.apollo-hubNav{box-sizing:border-box;flex:none;width:188px;display:flex;flex-direction:column;gap:2px;padding:12px 8px;border-right:1px solid var(--cfg-border);background:color-mix(in srgb,var(--cfg-ink) 2%,var(--cfg-surface));overflow-y:auto;scrollbar-width:thin}
|
|
223
|
+
.apollo-hubNavItem{display:flex;align-items:center;gap:10px;flex-shrink:0;min-height:32px;padding:0 10px;border:1px solid transparent;border-radius:8px;background:transparent;font:inherit;font-size:13px;line-height:20px;text-align:left;cursor:pointer;color:var(--cfg-ink-2);transition:background var(--cfg-dur) ease,color var(--cfg-dur) ease,border-color var(--cfg-dur) ease;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
246
224
|
.apollo-hubNavItem:hover{background:var(--cfg-hover);color:var(--cfg-ink)}
|
|
247
225
|
.apollo-hubNavItem[data-active]{background:var(--cfg-accent-soft);border-color:color-mix(in srgb,var(--cfg-accent) 25%,var(--cfg-border));color:var(--cfg-accent-ink);font-weight:500}
|
|
248
226
|
.apollo-hubNavItem svg{flex:none;opacity:.7}
|
|
249
227
|
.apollo-hubNavItem[data-active] svg{opacity:1;color:var(--cfg-accent-ink)}
|
|
250
228
|
.apollo-hubNavItem:focus-visible{outline:2px solid var(--cfg-accent);outline-offset:1px}
|
|
251
|
-
.apollo-hubContent{flex:1;min-width:0;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:24px
|
|
229
|
+
.apollo-hubContent{flex:1;min-width:0;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:24px 28px 32px;scrollbar-width:thin;scrollbar-gutter:stable}
|
|
252
230
|
.apollo-hubContent .apollo-footer{position:sticky;bottom:-1px;background:var(--cfg-surface);padding-bottom:12px;margin-top:auto}.apollo-hubPane{display:flex;flex-direction:column;min-height:100%}.apollo-hubPane>:first-child{flex:1 0 auto;min-height:0;display:flex;flex-direction:column}.apollo-root{flex:1;min-height:0;display:flex;flex-direction:column}.apollo-cfg{flex:1;min-height:0}.apollo-footer{margin-top:auto}
|
|
253
231
|
.apollo-hubModalContent{padding:0!important;overflow:hidden}
|
|
254
232
|
.apollo-hubPane{min-width:0;width:100%;overflow-wrap:anywhere}
|
|
@@ -260,11 +238,11 @@ window.__ModuleLoader__.load({
|
|
|
260
238
|
.apollo-modalHead{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 16px;border-bottom:1px solid var(--cfg-border)}
|
|
261
239
|
.apollo-modalTitle{margin:0;font-size:15px;font-weight:500;line-height:22px}
|
|
262
240
|
.apollo-modalBody{flex:1;min-height:0;overflow:hidden;display:flex}
|
|
263
|
-
.apollo-iconBtn{display:inline-flex;align-items:center;justify-content:center;width:
|
|
241
|
+
.apollo-iconBtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;border-radius:6px;background:transparent;color:var(--cfg-ink-3);font-size:16px;line-height:1;cursor:pointer}
|
|
264
242
|
.apollo-iconBtn:hover{background:var(--cfg-hover);color:var(--cfg-ink)}
|
|
265
243
|
.apollo-iconBtn:focus-visible{outline:2px solid var(--cfg-accent);outline-offset:1px}
|
|
266
244
|
@media (max-width:800px){.apollo-help>p{position:static;width:auto;max-width:none;margin-top:6px}.apollo-hub{flex-direction:column;height:min(80dvh,calc(100dvh - 24px))}.apollo-hubNav{width:auto;flex-direction:row;gap:4px;padding:8px;border-right:0;border-bottom:1px solid var(--cfg-border);overflow-x:auto}.apollo-hubNavItem{min-height:44px;flex:none}.apollo-hubContent{padding:20px 16px 24px}.apollo-cfg{gap:24px}.apollo-pageTitle{font-size:18px}.apollo-hubContent .apollo-footer{bottom:0}.apollo-mask{padding:12px}.apollo-modalCard{max-height:calc(100dvh - 24px)}}
|
|
267
|
-
@media (max-width:640px){.apollo-row{
|
|
245
|
+
@media (max-width:640px){.apollo-row{gap:12px;margin:0;padding:10px 0}.apollo-rowText{min-width:0;position:relative}.apollo-help{position:static}.apollo-row .apollo-switch{align-self:center}.apollo-footer{flex-wrap:wrap}.apollo-status{flex-basis:100%}.apollo-mask{padding:0}.apollo-modal.apollo-modal,.apollo-modalCard{flex-shrink:0;width:100vw;max-width:100vw;height:100dvh;max-height:100dvh;border:0;border-radius:0}.apollo-hubModalContent>:first-child button{width:44px;height:44px}.apollo-hub{height:calc(100dvh - 73px);min-height:0}.apollo-hubNav{scrollbar-width:none}.apollo-hubNav::-webkit-scrollbar{display:none}.apollo-help>button{width:44px;height:44px}.apollo-help>p{position:absolute;top:100%;left:0;right:auto;width:100%;max-width:none;box-sizing:border-box}}
|
|
268
246
|
@media (pointer:coarse),(max-width:640px){.apollo-iconBtn{width:44px;height:44px}.apollo-button{height:44px}}
|
|
269
247
|
@media (prefers-reduced-motion:reduce){.apollo-pulse{animation:none}.apollo-switch,.apollo-switchThumb,.apollo-button,.apollo-hubNavItem,.apollo-help>button{transition:none}}
|
|
270
248
|
`.trim();
|
|
@@ -290,13 +268,14 @@ window.__ModuleLoader__.load({
|
|
|
290
268
|
h('p', { id, hidden: !open, role: 'note' }, children));
|
|
291
269
|
}
|
|
292
270
|
|
|
293
|
-
function SwitchRow({ id, label, hint, checked, disabled, onChange }) {
|
|
271
|
+
function SwitchRow({ id, label, description, hint, checked, disabled, onChange }) {
|
|
294
272
|
const hintId = hint === undefined ? undefined : id + '-hint';
|
|
295
273
|
return h('div', { className: 'apollo-row' },
|
|
296
274
|
h('div', { className: 'apollo-rowText' },
|
|
297
275
|
h('div', { className: 'apollo-rowLabel' },
|
|
298
276
|
h('label', { className: 'apollo-rowTitle', htmlFor: id }, label),
|
|
299
|
-
hint === undefined ? null : h(Help, { label, id: hintId }, hint))
|
|
277
|
+
hint === undefined ? null : h(Help, { label, id: hintId }, hint)),
|
|
278
|
+
description === undefined ? null : h('div', { className: 'apollo-rowDesc' }, description)),
|
|
300
279
|
h('button', {
|
|
301
280
|
type: 'button',
|
|
302
281
|
id,
|
|
@@ -369,39 +348,32 @@ window.__ModuleLoader__.load({
|
|
|
369
348
|
|
|
370
349
|
return h('div', { className: 'apollo-cfg', 'data-settings-dirty': dirty, 'data-settings-busy': busy },
|
|
371
350
|
h('div', { className: 'apollo-pageHead' },
|
|
372
|
-
h('
|
|
351
|
+
h('div', { className: 'apollo-pageTitleBlock' },
|
|
352
|
+
h('h2', { className: 'apollo-pageTitle' }, translate('title')),
|
|
353
|
+
h('p', { className: 'apollo-pageSub' }, translate('purpose')))),
|
|
373
354
|
writable ? null : h('p', { className: 'apollo-note', 'data-tone': 'warn' }, translate('readonlyNote')),
|
|
374
355
|
h('section', { className: 'apollo-card' },
|
|
375
356
|
h('h3', { className: 'apollo-sectionTitle' }, translate('guardTitle')),
|
|
376
357
|
h(SwitchRow, {
|
|
377
358
|
id: 'apollo-exit-guard',
|
|
378
359
|
label: translate('exitGuardLabel'),
|
|
360
|
+
description: translate('exitGuardDescription'),
|
|
379
361
|
hint: translate('exitGuardHint'),
|
|
380
362
|
checked: live.exitGuard,
|
|
381
363
|
disabled: !writable || busy,
|
|
382
364
|
onChange: (next) => edit({ exitGuard: next }),
|
|
383
|
-
}),
|
|
384
|
-
h('div', { className: 'apollo-guardFlow', 'aria-hidden': 'true', 'data-enabled': live.exitGuard },
|
|
385
|
-
['guardEnd', 'guardJobs', live.exitGuard ? 'guardContinue' : 'guardAllow'].map((key, index) => h('div', { key, className: 'apollo-flowStep' },
|
|
386
|
-
h('svg', { width: 18, height: 18, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round' },
|
|
387
|
-
h('path', { d: ['M5 12h14m-6-6 6 6-6 6', 'M4 5h16v14H4ZM8 9l3 3-3 3m6 0h3', live.exitGuard ? 'M12 8v4l3 2M5 4 2 7m20 0-3-3M12 4a8 8 0 1 0 8 8' : 'M5 12l4 4L19 6'][index] })),
|
|
388
|
-
h('span', { className: 'apollo-flowLabel' }, translate(key)))))),
|
|
365
|
+
})),
|
|
389
366
|
h('section', { className: 'apollo-card' },
|
|
390
367
|
h('h3', { className: 'apollo-sectionTitle' }, translate('connectionTitle')),
|
|
391
368
|
h(SwitchRow, {
|
|
392
369
|
id: 'apollo-owns-host',
|
|
393
370
|
label: translate('ownsHostLabel'),
|
|
371
|
+
description: translate('ownsHostDescription'),
|
|
394
372
|
hint: translate('ownsHostHint') + ' ' + translate('ownsHostReload'),
|
|
395
373
|
checked: live.declareOwnsHost,
|
|
396
374
|
disabled: !writable || busy,
|
|
397
375
|
onChange: (next) => edit({ declareOwnsHost: next }),
|
|
398
376
|
})),
|
|
399
|
-
h('details', { className: 'apollo-details' },
|
|
400
|
-
h('summary', null, translate('compatTitle')),
|
|
401
|
-
h('div', { className: 'apollo-detailsBody' },
|
|
402
|
-
h('p', { className: 'apollo-hint' }, translate('migratedBody')),
|
|
403
|
-
h('p', { className: 'apollo-hint' }, translate('deprecatedBody')),
|
|
404
|
-
h('p', { className: 'apollo-hint' }, translate('reloadBody')))),
|
|
405
377
|
h('div', { className: 'apollo-footer', hidden: !dirty && !busy && notice === null },
|
|
406
378
|
status,
|
|
407
379
|
h('button', {
|