@prettier-ai/dsh-client-ui-settings-general 0.1.2-alpha.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/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +107 -0
- package/README.zh.md +107 -0
- package/lib/client.js +606 -0
- package/lib/index.js +15 -0
- package/lib/invariant.js +25 -0
- package/lib/types/client/GeneralSection.d.ts +11 -0
- package/lib/types/client/SettingsDocumentAction.d.ts +22 -0
- package/lib/types/client/SettingsRoot.d.ts +8 -0
- package/lib/types/client/chrome.d.ts +26 -0
- package/lib/types/client/index.d.ts +36 -0
- package/lib/types/client/locales.d.ts +22 -0
- package/lib/types/client/settings-document-store.d.ts +41 -0
- package/lib/types/client/shell-contract.d.ts +41 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/invariant.d.ts +16 -0
- package/package.json +89 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/client/ui-settings-general/README.md
|
|
5
|
+
README.md: f0c4ab7c50798919d42ade0eac6a9a93c8a4df1c
|
|
6
|
+
README.zh.md: 912ea0fb16c0d1d512ff846c8eda1e724664f1ea
|
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Settings shell, ownerless copy, and durable product-onboarding namespace for the dsh web client: the General section, trigger chrome, and onboarding ledger projection."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-client-ui-settings-general
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`dsh-client-ui-settings-general` is the settings shell of the dsh web client: the Settings panel opens from the sidebar's bottom control with the trigger chrome and modal shell, the navigation is built from the sections features contribute, and first-run users are walked through one onboarding step at a time. It also registers everything on the Settings pages that belongs to no single feature: the trigger/header/close chrome content, the local configuration-file action, the General section and its `settings.general.item` slot, and the `settings` dictionaries. Feature-owned rows (Permission, Language, Appearance), sections (Models), and conditional onboarding steps stay with their feature packages; the shell itself ships no onboarding copy of its own.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
Users reach the shell through the sidebar's bottom Settings control; feature plugins contribute their pages and onboarding steps through the slot ledgers this shell projects. The shell renders the modal panel, the navigation built from `settings.section` entries, and exactly one mounted onboarding step at a time.
|
|
29
|
+
|
|
30
|
+
### The General section
|
|
31
|
+
|
|
32
|
+
The General section holds rows registered into `settings.general.item` by feature packages — it has no built-in rows. Feature plugins own the row copy and behavior; the shell only provides the section and its slot. The Appearance row, for example, lives in ui-theme.
|
|
33
|
+
|
|
34
|
+
### Opening the configuration file
|
|
35
|
+
|
|
36
|
+
On a loopback browser, the shell renders **Open configuration file** only when the Host confirms that a provider-owned local document can be prepared. The action opens that document in the native text editor (bypassing the browser file association on macOS). Remote browsers never register the action and never issue the privileged settings read.
|
|
37
|
+
|
|
38
|
+
### Onboarding steps
|
|
39
|
+
|
|
40
|
+
The onboarding ledger projects in ascending order and mounts exactly one step at a time. Registrants own durable completion, capability readiness, copy, mutations, and their visible wrapper, so independently registered flows cannot stack and the shell does not become a second configuration fact source. Visible steps own their dialog chrome and app-root `inert` lifecycle.
|
|
41
|
+
|
|
42
|
+
-----
|
|
43
|
+
|
|
44
|
+
<a id="understand-the-implementation"></a>
|
|
45
|
+
## Understand the implementation
|
|
46
|
+
|
|
47
|
+
<details>
|
|
48
|
+
<summary>Implementation internals — click to expand</summary>
|
|
49
|
+
|
|
50
|
+
The shell owns the chrome and the projections; every piece of content and copy belongs to a registrant.
|
|
51
|
+
|
|
52
|
+
### Ledger projections
|
|
53
|
+
|
|
54
|
+
The navigation is a projection of the `settings.section` ledger; nav labels may be locale-following thunks, resolved through `resolveSlotLabel` and re-rendered on the section ledger bump or the locale revision (an optional `ctx.get('locale')` read; no hard locale dependency). The onboarding ledger projects in ascending order; the active registrant receives its id, `complete()`, and an `openSection(id)` callback, and completing or skipping transfers ownership to the next entry.
|
|
55
|
+
|
|
56
|
+
### Document availability
|
|
57
|
+
|
|
58
|
+
On a loopback page, the Client loads the provider's `hasDocument` capability through `settings/describe` and renders **Open configuration file** only when the Host confirms that a provider-owned local document can be prepared. The action calls the pathless, browser-authenticated `settings/openSettingsDocument` Remote; the Host resolves the provider path again, materializes an absent document, and hands it to a native text editor (`open -t` on macOS, bypassing a browser file association; the desktop file association on Linux and Windows; Windows association after `wslpath -w` translation on WSL). Open failures keep the action available and render a localized error. Reopening the dialog or reconnecting refreshes availability after a transient read failure or Host topology change. Non-loopback pages retain the Client policy that withholds this native action and its settings read.
|
|
59
|
+
|
|
60
|
+
### Host half
|
|
61
|
+
|
|
62
|
+
The Host half registers `ui-onboarding` in the user-settings seam. The welcome step contributed by ui-settings-models reads and writes its `welcomeNoticeVersion` through the existing public settings boundary; the shell itself remains policy-free.
|
|
63
|
+
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
-----
|
|
67
|
+
|
|
68
|
+
<a id="further-exploration"></a>
|
|
69
|
+
## Further Exploration
|
|
70
|
+
|
|
71
|
+
These pages cover the settings surface family and the composition model.
|
|
72
|
+
|
|
73
|
+
- [ui-settings](../ui-settings/README.md) — the domain base whose slot types and scope service this shell builds on.
|
|
74
|
+
- [ui-sidebar](../ui-sidebar/README.md) — the sidebar shell hosting the `sidebar.settings` seat.
|
|
75
|
+
- [ui-settings-models](../ui-settings-models/README.md) — the feature package contributing the DeepSeek onboarding step.
|
|
76
|
+
- [settings](../../settings/README.md) — the durable user-settings seam and its file provider.
|
|
77
|
+
- [Slot system standard](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md) — the composition model behind the ledgers.
|
|
78
|
+
|
|
79
|
+
-----
|
|
80
|
+
|
|
81
|
+
<a id="model-experience"></a>
|
|
82
|
+
## Model Experience
|
|
83
|
+
|
|
84
|
+
None, as the package is a browser-side UI plugin layer that registers nothing model-facing.
|
|
85
|
+
|
|
86
|
+
#### KV Cache effect
|
|
87
|
+
|
|
88
|
+
None; this package neither assembles nor sends a provider request.
|
|
89
|
+
|
|
90
|
+
## Known Limitations and Deferred Work
|
|
91
|
+
|
|
92
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
These limits define what the shell itself provides versus what features must supply; they are current package constraints.
|
|
96
|
+
|
|
97
|
+
- **The General section has no built-in rows** — each row appears only when its owning feature plugin is mounted; the shell cannot fill the section alone.
|
|
98
|
+
|
|
99
|
+
<a id="dev-note"></a>
|
|
100
|
+
### Dev Note
|
|
101
|
+
|
|
102
|
+
<details>
|
|
103
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
104
|
+
|
|
105
|
+
None.
|
|
106
|
+
|
|
107
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "dsh Web 客户端的设置外壳、无特定功能归属文案与持久化产品引导命名空间:「通用」分区、触发控件界面框架与引导账本投影。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-client-ui-settings-general
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`dsh-client-ui-settings-general` 是 dsh Web 客户端的设置外壳:Settings 面板从侧边栏底部的控件打开,带触发控件与模态外壳;导航由各功能贡献的分区构建;首次运行的用户一次只走一个引导步骤。它还注册设置页面上所有不属于单一功能的内容:触发器、标题栏与关闭控件界面框架、「本地配置文件」操作、「通用」分区及其 `settings.general.item` slot,以及 `settings` 字典。归具体功能所有的行(「权限」、「语言」、「外观」)、分区(「模型」)与条件式首次使用引导步骤仍由各自的功能包提供;外壳本身不自带任何引导文案。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
用户通过侧边栏底部的 Settings 控件进入外壳;功能插件通过本外壳所投影的 slot 账本贡献自己的页面与引导步骤。外壳渲染模态面板、由 `settings.section` 条目构建的导航,以及每次只挂载一个的引导步骤。
|
|
29
|
+
|
|
30
|
+
### 「通用」分区
|
|
31
|
+
|
|
32
|
+
「通用」分区承载由功能包注册进 `settings.general.item` 的行——它没有内置行。功能插件拥有行文案与行为;外壳只提供分区及其 slot。例如「外观」行位于 ui-theme。
|
|
33
|
+
|
|
34
|
+
### 打开配置文件
|
|
35
|
+
|
|
36
|
+
在回环浏览器上,只有当宿主确认可准备好一份由提供方持有的本地文档时,外壳才渲染**打开配置文件**。该操作会在原生文本编辑器中打开该文档(macOS 上绕过浏览器文件关联)。远程浏览器从不注册该操作,也从不发起这项特权设置读取。
|
|
37
|
+
|
|
38
|
+
### 引导步骤
|
|
39
|
+
|
|
40
|
+
引导账本按升序投影,每次只挂载一个步骤。注册方持有持久化完成状态、能力就绪状态、文案、变更操作与可见包装,因此独立注册的流程无法堆叠,外壳也不会成为第二个配置事实来源。可见步骤自行持有弹窗框架与应用根节点 `inert` 生命周期。
|
|
41
|
+
|
|
42
|
+
-----
|
|
43
|
+
|
|
44
|
+
<a id="understand-the-implementation"></a>
|
|
45
|
+
## 理解实现
|
|
46
|
+
|
|
47
|
+
<details>
|
|
48
|
+
<summary>实现细节——点击展开</summary>
|
|
49
|
+
|
|
50
|
+
外壳拥有界面框架与投影;每段内容与文案都属于某个注册方。
|
|
51
|
+
|
|
52
|
+
### 账本投影
|
|
53
|
+
|
|
54
|
+
导航是 `settings.section` 账本的投影;导航 label 可以是跟随语言的 thunk,经 `resolveSlotLabel` 解析,并在分区账本更新或 locale revision 变化时重新渲染(`ctx.get('locale')` 可选读取,无硬 locale 依赖)。引导账本按升序投影;当前注册方会收到该条目的 id、`complete()` 与 `openSection(id)` 回调,完成或跳过当前步骤后,所有权转交给下一项。
|
|
55
|
+
|
|
56
|
+
### 文档可用性
|
|
57
|
+
|
|
58
|
+
在 loopback 页面上,Client 通过 `settings/describe` 加载提供方的 `hasDocument` 能力,且只有在 Host 确认可准备好一份由提供方持有的本地文档时才渲染配置文件操作。该操作调用无路径参数且经浏览器认证的 `settings/openSettingsDocument` Remote;Host 会再次解析提供方路径、在文档缺失时将其创建出来,并交给原生文本编辑器(macOS 上使用 `open -t`,绕过浏览器文件关联;Linux 和 Windows 上使用桌面文件关联;WSL 上经 `wslpath -w` 转换后使用 Windows 文件关联)。打开失败时该操作仍可使用,并渲染本地化错误。临时读取失败或 Host 拓扑变化后,重新打开对话框或重新连接会刷新可用性。非 loopback 页面保留 Client 策略,不提供该原生操作及其 settings 读取。
|
|
59
|
+
|
|
60
|
+
### 宿主端
|
|
61
|
+
|
|
62
|
+
宿主端在用户设置 seam 中注册 `ui-onboarding`。`ui-settings-models` 提供的欢迎步骤通过既有公开 settings 边界读写其中的 `welcomeNoticeVersion`;外壳本身仍不持有产品策略。
|
|
63
|
+
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
-----
|
|
67
|
+
|
|
68
|
+
<a id="further-exploration"></a>
|
|
69
|
+
## 进一步探索
|
|
70
|
+
|
|
71
|
+
以下页面覆盖设置界面家族与组合模型。
|
|
72
|
+
|
|
73
|
+
- [ui-settings](../ui-settings/README.zh.md)——本外壳所依赖 slot 类型与 scope 服务所在的领域底座。
|
|
74
|
+
- [ui-sidebar](../ui-sidebar/README.zh.md)——承载 `sidebar.settings` 席位的侧边栏外壳。
|
|
75
|
+
- [ui-settings-models](../ui-settings-models/README.zh.md)——贡献 DeepSeek 引导步骤的功能包。
|
|
76
|
+
- [settings](../../settings/README.zh.md)——持久化用户设置 seam 及其文件提供方。
|
|
77
|
+
- [slot 系统标准](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.zh.md)——账本背后的组合模型。
|
|
78
|
+
|
|
79
|
+
-----
|
|
80
|
+
|
|
81
|
+
<a id="model-experience"></a>
|
|
82
|
+
## 模型体验
|
|
83
|
+
|
|
84
|
+
无。该包是浏览器端 UI 插件层,不注册任何面向模型的内容。
|
|
85
|
+
|
|
86
|
+
#### KV Cache 影响
|
|
87
|
+
|
|
88
|
+
无;该包既不组装也不发送提供方请求。
|
|
89
|
+
|
|
90
|
+
## 已知限制与延期工作
|
|
91
|
+
|
|
92
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
这些限制说明外壳自身提供什么、功能包必须提供什么;它们是当前包约束。
|
|
96
|
+
|
|
97
|
+
- **「通用」分区没有内置行**:每一行仅在其所属功能插件挂载时出现;外壳单独无法填满该分区。
|
|
98
|
+
|
|
99
|
+
<a id="dev-note"></a>
|
|
100
|
+
### 开发备注
|
|
101
|
+
|
|
102
|
+
<details>
|
|
103
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
104
|
+
|
|
105
|
+
无。
|
|
106
|
+
|
|
107
|
+
</details>
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@prettier-ai/dsh-client-ui-settings-general",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let _prettier_ai_dsh_client_ui_slots = require("@prettier-ai/dsh-client-ui-slots");
|
|
8
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
+
let react = require("react");
|
|
10
|
+
let _prettier_ai_dsh_client_ui_primitives = require("@prettier-ai/dsh-client-ui-primitives");
|
|
11
|
+
let _prettier_ai_dsh_client_store = require("@prettier-ai/dsh-client-store");
|
|
12
|
+
//#region ../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
13
|
+
function r(e) {
|
|
14
|
+
var t, f, n = "";
|
|
15
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
16
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
17
|
+
var o = e.length;
|
|
18
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
19
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
20
|
+
return n;
|
|
21
|
+
}
|
|
22
|
+
function clsx() {
|
|
23
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
24
|
+
return n;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region \0dsh-css:/home/runner/work/dsh-publisher/dsh-publisher/upstream/packages/client/ui-settings-general/src/client/SettingsRoot.module.css.mjs
|
|
28
|
+
const css$3 = ".eUC7PW_trigger{box-sizing:border-box;cursor:pointer;width:calc(100% + 4px);height:42px;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:12px;flex:none;align-items:center;gap:8px;margin:4px -2px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.eUC7PW_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.eUC7PW_trigger.eUC7PW_rail{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;margin:8px 0 10px;padding:0}.eUC7PW_triggerLabel{white-space:nowrap;overflow:hidden}.eUC7PW_overlay{z-index:1000;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.eUC7PW_mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}.eUC7PW_panel{z-index:1;background:var(--dsw-alias-bg-layer-2);width:800px;max-width:calc(100vw - 48px);height:min(800px,100vh - 48px);box-shadow:var(--dsw-shadow-lv3);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:24px;display:flex;position:relative;overflow:hidden}.eUC7PW_nav{box-sizing:border-box;flex-direction:column;flex:none;gap:18px;width:188px;padding:22px 12px 0;display:flex}.eUC7PW_navTitle{color:var(--dsw-alias-label-primary);padding:0 12px;font-size:16px;font-weight:500;line-height:24px}.eUC7PW_navList{flex-direction:column;gap:4px;display:flex}.eUC7PW_navCell{box-sizing:border-box;cursor:pointer;height:40px;color:var(--dsw-alias-label-primary);text-align:left;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:9px 16px 9px 12px;font-family:inherit;font-size:14px;font-weight:400;line-height:22px;display:flex}.eUC7PW_navCell:hover{background:var(--dsw-specific-sidebar-nav-item-hover)}.eUC7PW_navCell.eUC7PW_active{background:var(--dsw-specific-sidebar-nav-item-active)}.eUC7PW_navIcon{flex:none}.eUC7PW_navLabel{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.eUC7PW_content{flex-direction:column;flex:1;min-width:0;display:flex}.eUC7PW_header{box-sizing:border-box;flex:none;justify-content:space-between;align-items:flex-start;gap:8px;height:54px;padding:20px 14px 8px 10px;display:flex}.eUC7PW_actions{justify-content:flex-end;align-items:center;gap:8px;min-width:0;margin-left:auto;display:flex}.eUC7PW_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.eUC7PW_close:hover{background:var(--dsw-alias-interactive-bg-hover)}.eUC7PW_options{flex:1;min-height:0;padding:0 24px 24px;overflow-y:auto}.eUC7PW_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
|
|
29
|
+
const tagId$3 = "@prettier-ai/dsh-client-ui-settings-general/SettingsRoot.module.css";
|
|
30
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
31
|
+
const tag = document.createElement("style");
|
|
32
|
+
tag.dataset.plugin = "@prettier-ai/dsh-client-ui-settings-general";
|
|
33
|
+
tag.dataset.pluginCss = tagId$3;
|
|
34
|
+
tag.textContent = css$3;
|
|
35
|
+
document.head.appendChild(tag);
|
|
36
|
+
}
|
|
37
|
+
var SettingsRoot_module_css_default = {
|
|
38
|
+
"actions": "eUC7PW_actions",
|
|
39
|
+
"active": "eUC7PW_active",
|
|
40
|
+
"close": "eUC7PW_close",
|
|
41
|
+
"content": "eUC7PW_content",
|
|
42
|
+
"header": "eUC7PW_header",
|
|
43
|
+
"hiddenLabel": "eUC7PW_hiddenLabel",
|
|
44
|
+
"mask": "eUC7PW_mask",
|
|
45
|
+
"nav": "eUC7PW_nav",
|
|
46
|
+
"navCell": "eUC7PW_navCell",
|
|
47
|
+
"navIcon": "eUC7PW_navIcon",
|
|
48
|
+
"navLabel": "eUC7PW_navLabel",
|
|
49
|
+
"navList": "eUC7PW_navList",
|
|
50
|
+
"navTitle": "eUC7PW_navTitle",
|
|
51
|
+
"options": "eUC7PW_options",
|
|
52
|
+
"overlay": "eUC7PW_overlay",
|
|
53
|
+
"panel": "eUC7PW_panel",
|
|
54
|
+
"rail": "eUC7PW_rail",
|
|
55
|
+
"trigger": "eUC7PW_trigger",
|
|
56
|
+
"triggerLabel": "eUC7PW_triggerLabel"
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region lib/types/client/SettingsRoot.js
|
|
60
|
+
/**
|
|
61
|
+
* Settings shell root: the sidebar-foot trigger row plus the centered modal
|
|
62
|
+
* panel (figma 501:29947, 1080x700) with the section nav rail. The shell is
|
|
63
|
+
* a pure composition face — every piece of text (trigger label, panel title,
|
|
64
|
+
* close label, sections) arrives from registrants through slots; accessible
|
|
65
|
+
* names resolve to that content (trigger: its own text; dialog:
|
|
66
|
+
* aria-labelledby the title node; close: visually-hidden slot text). Modal
|
|
67
|
+
* open state and the active section id are component-local viewing state;
|
|
68
|
+
* the onboarding coordinator mounts exactly one ordered registrant while the
|
|
69
|
+
* sessions-derived empty-Hero fact is active. Visible dialog chrome belongs
|
|
70
|
+
* to the step, so a mounted-but-deciding step paints nothing here.
|
|
71
|
+
*/
|
|
72
|
+
/** Nav glyph by section id; unknown ids fall back to the settings gear. */
|
|
73
|
+
function navIcon(id) {
|
|
74
|
+
if (id === "models") return (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconDataOutline16, {
|
|
75
|
+
className: SettingsRoot_module_css_default.navIcon,
|
|
76
|
+
size: 16
|
|
77
|
+
});
|
|
78
|
+
if (id === "agent-presets") return (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconAgentPresetOutline16, {
|
|
79
|
+
className: SettingsRoot_module_css_default.navIcon,
|
|
80
|
+
size: 16
|
|
81
|
+
});
|
|
82
|
+
if (id === "plugins") return (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconPersonalizationOutline16, {
|
|
83
|
+
className: SettingsRoot_module_css_default.navIcon,
|
|
84
|
+
size: 16
|
|
85
|
+
});
|
|
86
|
+
return (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconSettingsOutline16, {
|
|
87
|
+
className: SettingsRoot_module_css_default.navIcon,
|
|
88
|
+
size: 16
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The modal layer: full-viewport mask + centered panel. Close paths: the
|
|
93
|
+
* header button, a mask click, and document-level Escape (mounted only while
|
|
94
|
+
* open, so the listener lifetime is the panel's).
|
|
95
|
+
*/
|
|
96
|
+
function SettingsPanel({ rows, renderSlot, activeId, onSelect, onClose }) {
|
|
97
|
+
const active = rows.find((r) => r.id === activeId)?.id ?? rows[0]?.id;
|
|
98
|
+
const titleId = (0, react.useId)();
|
|
99
|
+
(0, react.useEffect)(() => {
|
|
100
|
+
const onKeyDown = (e) => {
|
|
101
|
+
if (e.key === "Escape") onClose();
|
|
102
|
+
};
|
|
103
|
+
document.addEventListener("keydown", onKeyDown);
|
|
104
|
+
return () => {
|
|
105
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
106
|
+
};
|
|
107
|
+
}, [onClose]);
|
|
108
|
+
const closeButton = (0, react.useRef)(null);
|
|
109
|
+
(0, react.useEffect)(() => {
|
|
110
|
+
closeButton.current?.focus();
|
|
111
|
+
}, []);
|
|
112
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
113
|
+
className: SettingsRoot_module_css_default.overlay,
|
|
114
|
+
role: "presentation",
|
|
115
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
116
|
+
className: SettingsRoot_module_css_default.mask,
|
|
117
|
+
"aria-hidden": "true",
|
|
118
|
+
onClick: onClose
|
|
119
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
120
|
+
className: SettingsRoot_module_css_default.panel,
|
|
121
|
+
role: "dialog",
|
|
122
|
+
"aria-modal": "true",
|
|
123
|
+
"aria-labelledby": titleId,
|
|
124
|
+
children: [(0, react_jsx_runtime.jsxs)("nav", {
|
|
125
|
+
className: SettingsRoot_module_css_default.nav,
|
|
126
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
127
|
+
className: SettingsRoot_module_css_default.navTitle,
|
|
128
|
+
id: titleId,
|
|
129
|
+
children: renderSlot("settings.header", {})
|
|
130
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
131
|
+
className: SettingsRoot_module_css_default.navList,
|
|
132
|
+
children: rows.map((row) => (0, react_jsx_runtime.jsxs)("button", {
|
|
133
|
+
type: "button",
|
|
134
|
+
className: clsx(SettingsRoot_module_css_default.navCell, row.id === active && SettingsRoot_module_css_default.active),
|
|
135
|
+
"aria-current": row.id === active ? "true" : void 0,
|
|
136
|
+
onClick: () => {
|
|
137
|
+
onSelect(row.id);
|
|
138
|
+
},
|
|
139
|
+
children: [navIcon(row.id), (0, react_jsx_runtime.jsx)("span", {
|
|
140
|
+
className: SettingsRoot_module_css_default.navLabel,
|
|
141
|
+
children: row.label
|
|
142
|
+
})]
|
|
143
|
+
}, row.id))
|
|
144
|
+
})]
|
|
145
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
146
|
+
className: SettingsRoot_module_css_default.content,
|
|
147
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
148
|
+
className: SettingsRoot_module_css_default.header,
|
|
149
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
150
|
+
className: SettingsRoot_module_css_default.actions,
|
|
151
|
+
children: renderSlot("settings.action", {})
|
|
152
|
+
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
153
|
+
ref: closeButton,
|
|
154
|
+
type: "button",
|
|
155
|
+
className: SettingsRoot_module_css_default.close,
|
|
156
|
+
onClick: onClose,
|
|
157
|
+
children: [(0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 }), (0, react_jsx_runtime.jsx)("span", {
|
|
158
|
+
className: SettingsRoot_module_css_default.hiddenLabel,
|
|
159
|
+
children: renderSlot("settings.close", {})
|
|
160
|
+
})]
|
|
161
|
+
})]
|
|
162
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
163
|
+
className: SettingsRoot_module_css_default.options,
|
|
164
|
+
children: active !== void 0 && renderSlot("settings.section", { close: onClose }, { only: active })
|
|
165
|
+
})]
|
|
166
|
+
})]
|
|
167
|
+
})]
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Render the settings trigger and panel.
|
|
172
|
+
* @param props - composed slot props (contract/slots.ts).
|
|
173
|
+
* @returns the settings shell element tree.
|
|
174
|
+
*/
|
|
175
|
+
function SettingsRoot(props) {
|
|
176
|
+
const { wide, useSections, useOnboardingSteps, useSessions, renderSlot } = props;
|
|
177
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
178
|
+
const [activeId, setActiveId] = (0, react.useState)(void 0);
|
|
179
|
+
const [completedOnboarding, setCompletedOnboarding] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
180
|
+
const close = (0, react.useCallback)(() => {
|
|
181
|
+
setOpen(false);
|
|
182
|
+
setActiveId(void 0);
|
|
183
|
+
}, []);
|
|
184
|
+
const openSection = (0, react.useCallback)((id) => {
|
|
185
|
+
setActiveId(id);
|
|
186
|
+
setOpen(true);
|
|
187
|
+
}, []);
|
|
188
|
+
const rows = useSections((s) => s);
|
|
189
|
+
const onboardingSteps = useOnboardingSteps((s) => s);
|
|
190
|
+
const onboardingActive = useSessions((state) => state.phase === "ready" && (state.current === void 0 || state.byId[state.current]?.blank === true));
|
|
191
|
+
const onboardingStep = onboardingActive ? onboardingSteps.find((step) => !completedOnboarding.has(step.id)) : void 0;
|
|
192
|
+
(0, react.useEffect)(() => {
|
|
193
|
+
if (onboardingActive) return;
|
|
194
|
+
setCompletedOnboarding(/* @__PURE__ */ new Set());
|
|
195
|
+
}, [onboardingActive]);
|
|
196
|
+
const completeOnboardingStep = (0, react.useCallback)((id) => {
|
|
197
|
+
setCompletedOnboarding((previous) => {
|
|
198
|
+
if (previous.has(id)) return previous;
|
|
199
|
+
return new Set([...previous, id]);
|
|
200
|
+
});
|
|
201
|
+
}, []);
|
|
202
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
203
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
204
|
+
type: "button",
|
|
205
|
+
className: clsx(SettingsRoot_module_css_default.trigger, !wide && SettingsRoot_module_css_default.rail),
|
|
206
|
+
"aria-haspopup": "dialog",
|
|
207
|
+
"aria-expanded": open,
|
|
208
|
+
onClick: () => {
|
|
209
|
+
setOpen(true);
|
|
210
|
+
},
|
|
211
|
+
children: renderSlot("settings.trigger", { wide })
|
|
212
|
+
}),
|
|
213
|
+
open && (0, react_jsx_runtime.jsx)(SettingsPanel, {
|
|
214
|
+
rows,
|
|
215
|
+
renderSlot,
|
|
216
|
+
activeId,
|
|
217
|
+
onSelect: setActiveId,
|
|
218
|
+
onClose: close
|
|
219
|
+
}),
|
|
220
|
+
onboardingStep !== void 0 && renderSlot("settings.onboarding", {
|
|
221
|
+
stepId: onboardingStep.id,
|
|
222
|
+
complete: () => {
|
|
223
|
+
completeOnboardingStep(onboardingStep.id);
|
|
224
|
+
},
|
|
225
|
+
openSection
|
|
226
|
+
}, { only: onboardingStep.id })
|
|
227
|
+
] });
|
|
228
|
+
}
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region \0dsh-css:/home/runner/work/dsh-publisher/dsh-publisher/upstream/packages/client/ui-settings-general/src/client/chrome.module.css.mjs
|
|
231
|
+
const css$2 = ".WL4-9a_triggerLabel{white-space:nowrap;overflow:hidden}";
|
|
232
|
+
const tagId$2 = "@prettier-ai/dsh-client-ui-settings-general/chrome.module.css";
|
|
233
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
234
|
+
const tag = document.createElement("style");
|
|
235
|
+
tag.dataset.plugin = "@prettier-ai/dsh-client-ui-settings-general";
|
|
236
|
+
tag.dataset.pluginCss = tagId$2;
|
|
237
|
+
tag.textContent = css$2;
|
|
238
|
+
document.head.appendChild(tag);
|
|
239
|
+
}
|
|
240
|
+
var chrome_module_css_default = { "triggerLabel": "WL4-9a_triggerLabel" };
|
|
241
|
+
//#endregion
|
|
242
|
+
//#region lib/types/client/chrome.js
|
|
243
|
+
/**
|
|
244
|
+
* Shell chrome content registered into the shell's trigger/header seats: the
|
|
245
|
+
* trigger row icon + label (figma sidebar foot) and the panel title text.
|
|
246
|
+
* The shell renders the surrounding chrome (button, nav heading row) and
|
|
247
|
+
* reads each entry's `label` option for aria text.
|
|
248
|
+
*/
|
|
249
|
+
/**
|
|
250
|
+
* Render the trigger row content (icon; label only in the wide column).
|
|
251
|
+
* @param props - composed slot props.
|
|
252
|
+
* @returns the trigger content fragment.
|
|
253
|
+
*/
|
|
254
|
+
function TriggerContent({ wide, t }) {
|
|
255
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [wide ? (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconSettingsOutline16, { size: 16 }) : (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconSettingsOutline14, { size: 18 }), wide && (0, react_jsx_runtime.jsx)("span", {
|
|
256
|
+
className: chrome_module_css_default.triggerLabel,
|
|
257
|
+
children: t("trigger")
|
|
258
|
+
})] });
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Render the panel title text.
|
|
262
|
+
* @param props - composed slot props.
|
|
263
|
+
* @returns the title text node.
|
|
264
|
+
*/
|
|
265
|
+
function HeaderContent({ t }) {
|
|
266
|
+
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: t("title") });
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Render the close button's visually-hidden label text.
|
|
270
|
+
* @param props - composed slot props.
|
|
271
|
+
* @returns the label text node.
|
|
272
|
+
*/
|
|
273
|
+
function CloseLabel({ t }) {
|
|
274
|
+
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: t("close") });
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region \0dsh-css:/home/runner/work/dsh-publisher/dsh-publisher/upstream/packages/client/ui-settings-general/src/client/GeneralSection.module.css.mjs
|
|
278
|
+
const css$1 = ".gxVjla_section{flex-direction:column;width:100%;display:flex}.gxVjla_section>[data-slot=\"settings.general.item\"]>:last-child{border-bottom:none}";
|
|
279
|
+
const tagId$1 = "@prettier-ai/dsh-client-ui-settings-general/GeneralSection.module.css";
|
|
280
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
281
|
+
const tag = document.createElement("style");
|
|
282
|
+
tag.dataset.plugin = "@prettier-ai/dsh-client-ui-settings-general";
|
|
283
|
+
tag.dataset.pluginCss = tagId$1;
|
|
284
|
+
tag.textContent = css$1;
|
|
285
|
+
document.head.appendChild(tag);
|
|
286
|
+
}
|
|
287
|
+
var GeneralSection_module_css_default = { "section": "gxVjla_section" };
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region lib/types/client/GeneralSection.js
|
|
290
|
+
/**
|
|
291
|
+
* Render the General section content column.
|
|
292
|
+
* @param props - composed slot props (contract/slots.ts).
|
|
293
|
+
* @returns the section element tree.
|
|
294
|
+
*/
|
|
295
|
+
function GeneralSection({ renderSlot }) {
|
|
296
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
297
|
+
className: GeneralSection_module_css_default.section,
|
|
298
|
+
children: renderSlot("settings.general.item", {})
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region \0dsh-css:/home/runner/work/dsh-publisher/dsh-publisher/upstream/packages/client/ui-settings-general/src/client/SettingsDocumentAction.module.css.mjs
|
|
303
|
+
const css = ".lkm8fG_action{align-items:center;gap:8px;min-width:0;display:flex}.lkm8fG_error{max-width:180px;color:var(--dsw-alias-state-error-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}";
|
|
304
|
+
const tagId = "@prettier-ai/dsh-client-ui-settings-general/SettingsDocumentAction.module.css";
|
|
305
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
306
|
+
const tag = document.createElement("style");
|
|
307
|
+
tag.dataset.plugin = "@prettier-ai/dsh-client-ui-settings-general";
|
|
308
|
+
tag.dataset.pluginCss = tagId;
|
|
309
|
+
tag.textContent = css;
|
|
310
|
+
document.head.appendChild(tag);
|
|
311
|
+
}
|
|
312
|
+
var SettingsDocumentAction_module_css_default = {
|
|
313
|
+
"action": "lkm8fG_action",
|
|
314
|
+
"error": "lkm8fG_error"
|
|
315
|
+
};
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region lib/types/client/SettingsDocumentAction.js
|
|
318
|
+
/** Optional settings-header action for opening a file-backed Host document. */
|
|
319
|
+
/**
|
|
320
|
+
* Render the open-document action only after Host metadata confirms document availability.
|
|
321
|
+
* @param props - header owner props, localized copy, and injected document state.
|
|
322
|
+
* @returns the action, or null while unavailable or unresolved.
|
|
323
|
+
*/
|
|
324
|
+
function SettingsDocumentAction({ controller, useSnapshot, t }) {
|
|
325
|
+
const state = useSnapshot((snapshot) => snapshot);
|
|
326
|
+
(0, react.useEffect)(() => {
|
|
327
|
+
controller.load();
|
|
328
|
+
}, [controller]);
|
|
329
|
+
if (state.status !== "ready") return null;
|
|
330
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
331
|
+
className: SettingsDocumentAction_module_css_default.action,
|
|
332
|
+
children: [state.error === null ? null : (0, react_jsx_runtime.jsx)("span", {
|
|
333
|
+
className: SettingsDocumentAction_module_css_default.error,
|
|
334
|
+
role: "alert",
|
|
335
|
+
children: t("openDocument.error")
|
|
336
|
+
}), (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.Button, {
|
|
337
|
+
variant: "outline",
|
|
338
|
+
size: "sm",
|
|
339
|
+
disabled: state.opening,
|
|
340
|
+
onClick: () => {
|
|
341
|
+
controller.open();
|
|
342
|
+
},
|
|
343
|
+
children: t("openDocument")
|
|
344
|
+
})]
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
//#endregion
|
|
348
|
+
//#region lib/types/client/settings-document-store.js
|
|
349
|
+
/** State owner for the optional local settings-document action. */
|
|
350
|
+
function messageOf(error) {
|
|
351
|
+
return error instanceof Error ? error.message : String(error);
|
|
352
|
+
}
|
|
353
|
+
/** Derives local-document availability from the shared mirror and invokes the pathless Host-owned open operation. */
|
|
354
|
+
var SettingsDocumentStore = class {
|
|
355
|
+
remote;
|
|
356
|
+
describeFace;
|
|
357
|
+
/** uSES-safe state source shared by the registered header action. */
|
|
358
|
+
store = (0, _prettier_ai_dsh_client_store.createSnapshotStore)({
|
|
359
|
+
status: "idle",
|
|
360
|
+
opening: false,
|
|
361
|
+
error: null
|
|
362
|
+
});
|
|
363
|
+
following;
|
|
364
|
+
/**
|
|
365
|
+
* @param api - loopback settings wire face that opens the provider document.
|
|
366
|
+
* @param describeFace - the shared mirror's describe face (`hasDocument` source).
|
|
367
|
+
*/
|
|
368
|
+
constructor(remote, describeFace) {
|
|
369
|
+
this.remote = remote;
|
|
370
|
+
this.describeFace = describeFace;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Begin following the mirror (idempotent) and reflect whether the current
|
|
374
|
+
* provider owns a local document.
|
|
375
|
+
* @returns settlement once the snapshot reflects the mirror.
|
|
376
|
+
*/
|
|
377
|
+
async load() {
|
|
378
|
+
this.following ??= this.describeFace.subscribe(() => {
|
|
379
|
+
this.derive();
|
|
380
|
+
});
|
|
381
|
+
this.store.update((state) => {
|
|
382
|
+
state.status = "loading";
|
|
383
|
+
state.error = null;
|
|
384
|
+
});
|
|
385
|
+
await this.describeFace.ensure();
|
|
386
|
+
this.derive();
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Open the loaded document once; concurrent gestures collapse behind the in-flight action.
|
|
390
|
+
* @returns after the native-open request settles, or immediately when unavailable/already opening.
|
|
391
|
+
*/
|
|
392
|
+
async open() {
|
|
393
|
+
const current = this.store.getSnapshot();
|
|
394
|
+
if (current.status !== "ready" || current.opening) return;
|
|
395
|
+
this.store.update((state) => {
|
|
396
|
+
state.opening = true;
|
|
397
|
+
state.error = null;
|
|
398
|
+
});
|
|
399
|
+
try {
|
|
400
|
+
const result = await this.remote.settings.openSettingsDocument();
|
|
401
|
+
if (!result.ok) throw new Error(result.error.message);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
this.store.update((state) => {
|
|
404
|
+
state.error = messageOf(error);
|
|
405
|
+
});
|
|
406
|
+
} finally {
|
|
407
|
+
this.store.update((state) => {
|
|
408
|
+
state.opening = false;
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/** Stop following the mirror. */
|
|
413
|
+
dispose() {
|
|
414
|
+
this.following?.();
|
|
415
|
+
this.following = void 0;
|
|
416
|
+
}
|
|
417
|
+
derive() {
|
|
418
|
+
const mirrored = this.describeFace.getSnapshot();
|
|
419
|
+
if (mirrored.view === void 0) {
|
|
420
|
+
if (mirrored.error !== null) this.store.update((state) => {
|
|
421
|
+
state.status = "unavailable";
|
|
422
|
+
state.error = mirrored.error;
|
|
423
|
+
});
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
const { hasDocument } = mirrored.view;
|
|
427
|
+
this.store.update((state) => {
|
|
428
|
+
state.status = hasDocument ? "ready" : "unavailable";
|
|
429
|
+
state.error = null;
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
//#endregion
|
|
434
|
+
//#region lib/types/client/locales.js
|
|
435
|
+
/** Shell chrome and General-nav dictionaries; feature rows own their copy. */
|
|
436
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
437
|
+
const zh = {
|
|
438
|
+
"trigger": "设置",
|
|
439
|
+
"title": "设置",
|
|
440
|
+
"close": "关闭",
|
|
441
|
+
"openDocument": "打开配置文件",
|
|
442
|
+
"openDocument.error": "无法打开配置文件",
|
|
443
|
+
"general.nav": "通用设置"
|
|
444
|
+
};
|
|
445
|
+
/** English dictionary, checked complete against the zh key set. */
|
|
446
|
+
const en = {
|
|
447
|
+
"trigger": "Settings",
|
|
448
|
+
"title": "Settings",
|
|
449
|
+
"close": "Close",
|
|
450
|
+
"openDocument": "Open configuration file",
|
|
451
|
+
"openDocument.error": "Could not open configuration file",
|
|
452
|
+
"general.nav": "General"
|
|
453
|
+
};
|
|
454
|
+
//#endregion
|
|
455
|
+
//#region lib/types/client/index.js
|
|
456
|
+
/** Dictionary namespace owned by this plugin (shell chrome + General copy). */
|
|
457
|
+
const NS = "settings";
|
|
458
|
+
/**
|
|
459
|
+
* Required services (cordis fiber inject). The target slots are declared by
|
|
460
|
+
* ui-settings' apply, whose activation order relative to this one is NOT
|
|
461
|
+
* constrained; registrations depend on their slots through `slots.inject()`.
|
|
462
|
+
*/
|
|
463
|
+
const inject = [
|
|
464
|
+
"slots",
|
|
465
|
+
"locale",
|
|
466
|
+
"connection",
|
|
467
|
+
"remote",
|
|
468
|
+
"remote.settings",
|
|
469
|
+
"settingsScope"
|
|
470
|
+
];
|
|
471
|
+
/**
|
|
472
|
+
* Register the `settings` dictionaries, the chrome content, and the General
|
|
473
|
+
* section, each once its slot declaration is on the ledger.
|
|
474
|
+
* @param ctx - client root context.
|
|
475
|
+
*/
|
|
476
|
+
function apply(ctx) {
|
|
477
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
478
|
+
zh,
|
|
479
|
+
en
|
|
480
|
+
}), "ui-settings-general: dictionaries");
|
|
481
|
+
const t = ctx.locale.bind(NS);
|
|
482
|
+
const documentController = ctx.get("connection").isLoopback ? new SettingsDocumentStore(ctx.remote, ctx.settingsScope.describe()) : void 0;
|
|
483
|
+
const documentInjected = documentController === void 0 ? void 0 : () => ({
|
|
484
|
+
controller: documentController,
|
|
485
|
+
hooks: { snapshot: documentController.store }
|
|
486
|
+
});
|
|
487
|
+
ctx.effect(() => () => {
|
|
488
|
+
documentController?.dispose();
|
|
489
|
+
}, "ui-settings-general: document action directory");
|
|
490
|
+
let rowsVersion = -1;
|
|
491
|
+
let rowsRevision = -1;
|
|
492
|
+
let rows = [];
|
|
493
|
+
let onboardingVersion = -1;
|
|
494
|
+
let onboardingSteps = [];
|
|
495
|
+
const shellInjected = () => ({ hooks: {
|
|
496
|
+
sections: {
|
|
497
|
+
getSnapshot: () => {
|
|
498
|
+
const version = ctx.slots.getVersion("settings.section");
|
|
499
|
+
const revision = ctx.locale.getSnapshot().revision;
|
|
500
|
+
if (version !== rowsVersion || revision !== rowsRevision) {
|
|
501
|
+
rowsVersion = version;
|
|
502
|
+
rowsRevision = revision;
|
|
503
|
+
rows = ctx.slots.entries("settings.section").map((e) => ({
|
|
504
|
+
/* v8 ignore next -- list-slot registration requires id (SlotCore rejects an entry without one) */
|
|
505
|
+
id: e.options.id ?? "",
|
|
506
|
+
order: e.options.order ?? 0,
|
|
507
|
+
label: (0, _prettier_ai_dsh_client_ui_slots.resolveSlotLabel)(e.options.label) ?? ""
|
|
508
|
+
})).sort((a, b) => a.order - b.order);
|
|
509
|
+
}
|
|
510
|
+
return rows;
|
|
511
|
+
},
|
|
512
|
+
subscribe: (listener) => {
|
|
513
|
+
const offLedger = ctx.slots.subscribe("settings.section", listener);
|
|
514
|
+
const offLocale = ctx.locale.subscribe(listener);
|
|
515
|
+
return () => {
|
|
516
|
+
offLedger();
|
|
517
|
+
offLocale();
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
onboardingSteps: {
|
|
522
|
+
getSnapshot: () => {
|
|
523
|
+
const version = ctx.slots.getVersion("settings.onboarding");
|
|
524
|
+
if (version !== onboardingVersion) {
|
|
525
|
+
onboardingVersion = version;
|
|
526
|
+
onboardingSteps = ctx.slots.entries("settings.onboarding").map((e) => ({
|
|
527
|
+
/* v8 ignore next -- list-slot registration requires id */
|
|
528
|
+
id: e.options.id ?? "",
|
|
529
|
+
order: e.options.order ?? 0
|
|
530
|
+
})).sort((a, b) => a.order - b.order);
|
|
531
|
+
}
|
|
532
|
+
return onboardingSteps;
|
|
533
|
+
},
|
|
534
|
+
subscribe: (listener) => ctx.slots.subscribe("settings.onboarding", listener)
|
|
535
|
+
}
|
|
536
|
+
} });
|
|
537
|
+
ctx.slots.inject("sidebar.settings", () => ctx.slots.register({
|
|
538
|
+
name: "sidebar.settings",
|
|
539
|
+
children: {
|
|
540
|
+
"settings.trigger": {
|
|
541
|
+
kind: "single",
|
|
542
|
+
scope: "root"
|
|
543
|
+
},
|
|
544
|
+
"settings.header": {
|
|
545
|
+
kind: "single",
|
|
546
|
+
scope: "root"
|
|
547
|
+
},
|
|
548
|
+
"settings.action": {
|
|
549
|
+
kind: "list",
|
|
550
|
+
scope: "root"
|
|
551
|
+
},
|
|
552
|
+
"settings.close": {
|
|
553
|
+
kind: "single",
|
|
554
|
+
scope: "root"
|
|
555
|
+
},
|
|
556
|
+
"settings.section": {
|
|
557
|
+
kind: "list",
|
|
558
|
+
scope: "root"
|
|
559
|
+
},
|
|
560
|
+
"settings.onboarding": {
|
|
561
|
+
kind: "list",
|
|
562
|
+
scope: "root"
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
inject: shellInjected
|
|
566
|
+
}, SettingsRoot));
|
|
567
|
+
ctx.slots.inject("settings.trigger", () => ctx.slots.register({
|
|
568
|
+
name: "settings.trigger",
|
|
569
|
+
locale: NS
|
|
570
|
+
}, TriggerContent));
|
|
571
|
+
ctx.slots.inject("settings.header", () => ctx.slots.register({
|
|
572
|
+
name: "settings.header",
|
|
573
|
+
locale: NS
|
|
574
|
+
}, HeaderContent));
|
|
575
|
+
if (documentInjected !== void 0) ctx.slots.inject("settings.action", () => ctx.slots.register({
|
|
576
|
+
name: "settings.action",
|
|
577
|
+
id: "open-document",
|
|
578
|
+
order: 0,
|
|
579
|
+
locale: NS,
|
|
580
|
+
inject: documentInjected
|
|
581
|
+
}, SettingsDocumentAction));
|
|
582
|
+
ctx.slots.inject("settings.close", () => ctx.slots.register({
|
|
583
|
+
name: "settings.close",
|
|
584
|
+
locale: NS
|
|
585
|
+
}, CloseLabel));
|
|
586
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
587
|
+
name: "settings.section",
|
|
588
|
+
id: "general",
|
|
589
|
+
order: 0,
|
|
590
|
+
label: () => t("general.nav"),
|
|
591
|
+
locale: NS,
|
|
592
|
+
children: { "settings.general.item": {
|
|
593
|
+
kind: "list",
|
|
594
|
+
scope: "root"
|
|
595
|
+
} }
|
|
596
|
+
}, GeneralSection));
|
|
597
|
+
}
|
|
598
|
+
//#endregion
|
|
599
|
+
exports.SettingsDocumentStore = SettingsDocumentStore;
|
|
600
|
+
exports.apply = apply;
|
|
601
|
+
exports.inject = inject;
|
|
602
|
+
return module.exports;
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
//# sourceMappingURL=client.js.map
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import z from "@prettier-ai/schemastery";
|
|
2
|
+
import { settingsNamespace } from "@prettier-ai/dsh-settings";
|
|
3
|
+
//#region lib/types/index.js
|
|
4
|
+
/** Host loader entry for the browser implementation exported from `./client`. */
|
|
5
|
+
/** Durable settings namespace for product-wide GUI onboarding facts. */
|
|
6
|
+
const ONBOARDING_SETTINGS_NAMESPACE = "ui-onboarding";
|
|
7
|
+
const OnboardingSettingsSchema = z.object({ welcomeNoticeVersion: z.string() });
|
|
8
|
+
/** Register the durable GUI-onboarding section when a settings provider exists. */
|
|
9
|
+
function apply(ctx) {
|
|
10
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
11
|
+
settingsCtx.settings.register(settingsNamespace(ONBOARDING_SETTINGS_NAMESPACE), OnboardingSettingsSchema);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { apply };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@prettier-ai/dsh-client-ui-settings-general`.
|
|
4
|
+
* @module @prettier-ai/dsh-client-ui-settings-general/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@prettier-ai/dsh-client-ui-settings-general";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "client-ui-settings-general-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: the settings seam validates and publishes the durable
|
|
13
|
+
* onboarding section, while slot conflicts fail loud in the slot core. The local
|
|
14
|
+
* document action is browser state over typed RPC responses and is covered by
|
|
15
|
+
* store/component tests rather than a Cordis runtime relationship.
|
|
16
|
+
*/
|
|
17
|
+
const install = () => {};
|
|
18
|
+
/**
|
|
19
|
+
* Register this package's invariant companion.
|
|
20
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
21
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
22
|
+
*/
|
|
23
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
24
|
+
//#endregion
|
|
25
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** The General section: one column rendering feature-owned item contributions. */
|
|
2
|
+
import type { PropsRenderSlots, PropsRuntime } from '@prettier-ai/dsh-client-ui-slots';
|
|
3
|
+
/** Full component props: section owner share plus item render share. */
|
|
4
|
+
export type GeneralSectionComponentProps = PropsRuntime<'settings.section'> & PropsRenderSlots<'settings.general.item'>;
|
|
5
|
+
/**
|
|
6
|
+
* Render the General section content column.
|
|
7
|
+
* @param props - composed slot props (contract/slots.ts).
|
|
8
|
+
* @returns the section element tree.
|
|
9
|
+
*/
|
|
10
|
+
export declare function GeneralSection({ renderSlot }: GeneralSectionComponentProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=GeneralSection.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Optional settings-header action for opening a file-backed Host document. */
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from '@prettier-ai/dsh-client-ui-slots';
|
|
4
|
+
import type { SettingsDocumentStore } from './settings-document-store.ts';
|
|
5
|
+
/** Registrant-owned dependencies of {@link SettingsDocumentAction}. */
|
|
6
|
+
export interface SettingsDocumentActionInjected {
|
|
7
|
+
/** Provider metadata and action state owner. */
|
|
8
|
+
controller: SettingsDocumentStore;
|
|
9
|
+
hooks: {
|
|
10
|
+
/** Controller snapshot bound by the UI renderer as useSnapshot. */
|
|
11
|
+
snapshot: SettingsDocumentStore['store'];
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Header-action owner share, localized copy, and the registrant's state face. */
|
|
15
|
+
export type SettingsDocumentActionProps = PropsRuntime<'settings.action'> & PropsLocale<'settings'> & InjectFace<SettingsDocumentActionInjected>;
|
|
16
|
+
/**
|
|
17
|
+
* Render the open-document action only after Host metadata confirms document availability.
|
|
18
|
+
* @param props - header owner props, localized copy, and injected document state.
|
|
19
|
+
* @returns the action, or null while unavailable or unresolved.
|
|
20
|
+
*/
|
|
21
|
+
export declare function SettingsDocumentAction({ controller, useSnapshot, t }: SettingsDocumentActionProps): ReactNode;
|
|
22
|
+
//# sourceMappingURL=SettingsDocumentAction.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SettingsRootComponentProps } from './shell-contract.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Render the settings trigger and panel.
|
|
4
|
+
* @param props - composed slot props (contract/slots.ts).
|
|
5
|
+
* @returns the settings shell element tree.
|
|
6
|
+
*/
|
|
7
|
+
export declare function SettingsRoot(props: SettingsRootComponentProps): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=SettingsRoot.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@prettier-ai/dsh-client-ui-slots';
|
|
2
|
+
/** Trigger content props: the sidebar column state + the standard locale seat. */
|
|
3
|
+
export type TriggerContentProps = PropsRuntime<'settings.trigger'> & PropsLocale<'settings'>;
|
|
4
|
+
/** Header content props: the standard locale seat only. */
|
|
5
|
+
export type HeaderContentProps = PropsRuntime<'settings.header'> & PropsLocale<'settings'>;
|
|
6
|
+
/**
|
|
7
|
+
* Render the trigger row content (icon; label only in the wide column).
|
|
8
|
+
* @param props - composed slot props.
|
|
9
|
+
* @returns the trigger content fragment.
|
|
10
|
+
*/
|
|
11
|
+
export declare function TriggerContent({ wide, t }: TriggerContentProps): import("react").JSX.Element;
|
|
12
|
+
/**
|
|
13
|
+
* Render the panel title text.
|
|
14
|
+
* @param props - composed slot props.
|
|
15
|
+
* @returns the title text node.
|
|
16
|
+
*/
|
|
17
|
+
export declare function HeaderContent({ t }: HeaderContentProps): import("react").JSX.Element;
|
|
18
|
+
/** Close-button label text props: the standard locale seat only. */
|
|
19
|
+
export type CloseLabelProps = PropsRuntime<'settings.close'> & PropsLocale<'settings'>;
|
|
20
|
+
/**
|
|
21
|
+
* Render the close button's visually-hidden label text.
|
|
22
|
+
* @param props - composed slot props.
|
|
23
|
+
* @returns the label text node.
|
|
24
|
+
*/
|
|
25
|
+
export declare function CloseLabel({ t }: CloseLabelProps): import("react").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=chrome.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings shell and ownerless-copy plugin, browser half: renders the
|
|
3
|
+
* `sidebar.settings` occupant — panel chrome, section navigation, and the
|
|
4
|
+
* onboarding stage — and registers everything on the Settings pages that
|
|
5
|
+
* belongs to no single feature: the trigger/header chrome content,
|
|
6
|
+
* local-document action, General section, and `settings` dictionaries.
|
|
7
|
+
* Feature-owned rows and sections stay with their features.
|
|
8
|
+
* Export discipline: packages/client/AGENTS.md.
|
|
9
|
+
*/
|
|
10
|
+
import type { Context as ClientContext } from '@prettier-ai/cordis';
|
|
11
|
+
import { type SettingsKey } from './locales.ts';
|
|
12
|
+
export type { CloseLabelProps, HeaderContentProps, TriggerContentProps, } from './chrome.tsx';
|
|
13
|
+
export type { GeneralSectionComponentProps, } from './GeneralSection.tsx';
|
|
14
|
+
export type { SettingsDocumentActionInjected, SettingsDocumentActionProps } from './SettingsDocumentAction.tsx';
|
|
15
|
+
export type { SettingsDocumentState } from './settings-document-store.ts';
|
|
16
|
+
export { SettingsDocumentStore } from './settings-document-store.ts';
|
|
17
|
+
export type { SettingsKey } from './locales.ts';
|
|
18
|
+
declare module '@prettier-ai/dsh-client-ui-slots' {
|
|
19
|
+
interface LocaleNamespaceMap {
|
|
20
|
+
/** Shell chrome + shell-owned General section copy. */
|
|
21
|
+
settings: SettingsKey;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Required services (cordis fiber inject). The target slots are declared by
|
|
26
|
+
* ui-settings' apply, whose activation order relative to this one is NOT
|
|
27
|
+
* constrained; registrations depend on their slots through `slots.inject()`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const inject: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Register the `settings` dictionaries, the chrome content, and the General
|
|
32
|
+
* section, each once its slot declaration is on the ledger.
|
|
33
|
+
* @param ctx - client root context.
|
|
34
|
+
*/
|
|
35
|
+
export declare function apply(ctx: ClientContext): void;
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Shell chrome and General-nav dictionaries; feature rows own their copy. */
|
|
2
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
3
|
+
export declare const zh: {
|
|
4
|
+
trigger: string;
|
|
5
|
+
title: string;
|
|
6
|
+
close: string;
|
|
7
|
+
openDocument: string;
|
|
8
|
+
'openDocument.error': string;
|
|
9
|
+
'general.nav': string;
|
|
10
|
+
};
|
|
11
|
+
/** The settings namespace key union. */
|
|
12
|
+
export type SettingsKey = keyof typeof zh;
|
|
13
|
+
/** English dictionary, checked complete against the zh key set. */
|
|
14
|
+
export declare const en: {
|
|
15
|
+
trigger: string;
|
|
16
|
+
title: string;
|
|
17
|
+
close: string;
|
|
18
|
+
openDocument: string;
|
|
19
|
+
'openDocument.error': string;
|
|
20
|
+
'general.nav': string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** State owner for the optional local settings-document action. */
|
|
2
|
+
import type { ClientRemote } from '@prettier-ai/dsh-api-remotes/client';
|
|
3
|
+
import { type SnapshotStore } from '@prettier-ai/dsh-client-store';
|
|
4
|
+
import type { SettingsDescribeFace } from '@prettier-ai/dsh-client-ui-settings/client';
|
|
5
|
+
/** Browser state of the Host-owned settings document. */
|
|
6
|
+
export interface SettingsDocumentState {
|
|
7
|
+
/** Metadata-loading phase; unavailable means the provider has no local document or the read failed. */
|
|
8
|
+
status: 'idle' | 'loading' | 'ready' | 'unavailable';
|
|
9
|
+
/** Whether one native-open request is in flight. */
|
|
10
|
+
opening: boolean;
|
|
11
|
+
/** Last metadata/native-open diagnostic; UI exposes only localized copy. */
|
|
12
|
+
error: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** Derives local-document availability from the shared mirror and invokes the pathless Host-owned open operation. */
|
|
15
|
+
export declare class SettingsDocumentStore {
|
|
16
|
+
private readonly remote;
|
|
17
|
+
private readonly describeFace;
|
|
18
|
+
/** uSES-safe state source shared by the registered header action. */
|
|
19
|
+
readonly store: SnapshotStore<SettingsDocumentState>;
|
|
20
|
+
private following;
|
|
21
|
+
/**
|
|
22
|
+
* @param api - loopback settings wire face that opens the provider document.
|
|
23
|
+
* @param describeFace - the shared mirror's describe face (`hasDocument` source).
|
|
24
|
+
*/
|
|
25
|
+
constructor(remote: Pick<ClientRemote, 'settings'>, describeFace: SettingsDescribeFace);
|
|
26
|
+
/**
|
|
27
|
+
* Begin following the mirror (idempotent) and reflect whether the current
|
|
28
|
+
* provider owns a local document.
|
|
29
|
+
* @returns settlement once the snapshot reflects the mirror.
|
|
30
|
+
*/
|
|
31
|
+
load(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Open the loaded document once; concurrent gestures collapse behind the in-flight action.
|
|
34
|
+
* @returns after the native-open request settles, or immediately when unavailable/already opening.
|
|
35
|
+
*/
|
|
36
|
+
open(): Promise<void>;
|
|
37
|
+
/** Stop following the mirror. */
|
|
38
|
+
dispose(): void;
|
|
39
|
+
private derive;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=settings-document-store.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings shell contract — the types of the `sidebar.settings` occupant this
|
|
3
|
+
* package renders. They live here rather than in ui-settings because they
|
|
4
|
+
* reference the sidebar's own slot type: ui-settings is the settings domain's
|
|
5
|
+
* base layer and must not depend on any `ui-*` presentation package, or the
|
|
6
|
+
* reference graph closes a cycle through ui-sidebar → ui-layout → ui-theme.
|
|
7
|
+
* The settings SLOT types (what registrants contribute) stay in ui-settings.
|
|
8
|
+
*/
|
|
9
|
+
import type { HostObservable, InjectFace, PropsRenderSlots, PropsRuntime } from '@prettier-ai/dsh-client-ui-slots';
|
|
10
|
+
/** One nav row projected from a settings.section registration's options. */
|
|
11
|
+
export interface SettingsSectionRow {
|
|
12
|
+
id: string;
|
|
13
|
+
order: number;
|
|
14
|
+
label: string;
|
|
15
|
+
}
|
|
16
|
+
/** One ordered onboarding step projected from a slot registration. */
|
|
17
|
+
export interface SettingsOnboardingStep {
|
|
18
|
+
id: string;
|
|
19
|
+
order: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Registrant-private injected share of the settings shell (assembled in
|
|
23
|
+
* apply): the ledger's nav-row projection as a hooks-compartment source —
|
|
24
|
+
* the shell reads no locale state and subscribes through the bound hook.
|
|
25
|
+
*/
|
|
26
|
+
export type SettingsRootInjected = {
|
|
27
|
+
hooks: {
|
|
28
|
+
/** settings.section ledger projected into ordered nav rows. */
|
|
29
|
+
sections: HostObservable<readonly SettingsSectionRow[]>;
|
|
30
|
+
/** settings.onboarding ledger projected into coordinator order. */
|
|
31
|
+
onboardingSteps: HostObservable<readonly SettingsOnboardingStep[]>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Full component props of the settings shell root: the sidebar owner share
|
|
36
|
+
* (wide/rail state) plus the declared render shares and the injected face
|
|
37
|
+
* (hooks compartment bound to useSections). No store is registered — modal
|
|
38
|
+
* open state and active section id are component-local viewing state.
|
|
39
|
+
*/
|
|
40
|
+
export type SettingsRootComponentProps = PropsRuntime<'sidebar.settings'> & PropsRenderSlots<'settings.trigger' | 'settings.header' | 'settings.action' | 'settings.close' | 'settings.section' | 'settings.onboarding'> & InjectFace<SettingsRootInjected>;
|
|
41
|
+
//# sourceMappingURL=shell-contract.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Host loader entry for the browser implementation exported from `./client`. */
|
|
2
|
+
import type { Context } from '@prettier-ai/cordis';
|
|
3
|
+
/** Register the durable GUI-onboarding section when a settings provider exists. */
|
|
4
|
+
export declare function apply(ctx: Context): void;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@prettier-ai/dsh-client-ui-settings-general`.
|
|
3
|
+
* @module @prettier-ai/dsh-client-ui-settings-general/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@prettier-ai/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "client-ui-settings-general-invariant";
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prettier-ai/dsh-client-ui-settings-general",
|
|
3
|
+
"description": "Settings ownerless-copy and product onboarding plugin: the General section, shell trigger/header chrome content, settings dictionaries, and the versioned welcome notice",
|
|
4
|
+
"version": "0.1.2-alpha.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/client/ui-settings-general"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./client": {
|
|
26
|
+
"types": "./lib/types/client/index.d.ts",
|
|
27
|
+
"default": "./lib/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./src/*": "./src/*",
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"dsh": {
|
|
33
|
+
"client": {
|
|
34
|
+
"inject": [
|
|
35
|
+
"@prettier-ai/dsh-client-ui-settings",
|
|
36
|
+
"@prettier-ai/dsh-client-locale",
|
|
37
|
+
"@prettier-ai/dsh-client-connection",
|
|
38
|
+
"@prettier-ai/dsh-api-remotes",
|
|
39
|
+
"@prettier-ai/dsh-client-ui-sidebar"
|
|
40
|
+
],
|
|
41
|
+
"platform": "web"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"clsx": "^2.0.0",
|
|
47
|
+
"@prettier-ai/schemastery": "^3.18.1"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.1",
|
|
51
|
+
"@prettier-ai/dsh-client-ui-settings": "^0.1.2-alpha.1",
|
|
52
|
+
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.1",
|
|
53
|
+
"@prettier-ai/cordis": "^4.0.1",
|
|
54
|
+
"@prettier-ai/dsh-client-connection": "^0.1.2-alpha.1",
|
|
55
|
+
"@prettier-ai/dsh-client-ui-sidebar": "^0.1.2-alpha.1",
|
|
56
|
+
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.1",
|
|
57
|
+
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.1",
|
|
58
|
+
"@prettier-ai/dsh-client-ui-session": "^0.1.2-alpha.1",
|
|
59
|
+
"@prettier-ai/dsh-settings": "^0.1.2-alpha.1"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/react": "~18.3.1",
|
|
63
|
+
"react": "^18.2.0",
|
|
64
|
+
"@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.1",
|
|
65
|
+
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.1",
|
|
66
|
+
"@prettier-ai/dsh-client-connection": "^0.1.2-alpha.1",
|
|
67
|
+
"@prettier-ai/dsh-client-store": "^0.1.2-alpha.1",
|
|
68
|
+
"@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.1",
|
|
69
|
+
"@prettier-ai/dsh-client-ui-settings": "^0.1.2-alpha.1",
|
|
70
|
+
"@prettier-ai/dsh-client-ui-primitives": "^0.1.2-alpha.1",
|
|
71
|
+
"@prettier-ai/dsh-client-ui-slots": "^0.1.2-alpha.1",
|
|
72
|
+
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.1",
|
|
73
|
+
"@prettier-ai/cordis": "^4.0.1",
|
|
74
|
+
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.1",
|
|
75
|
+
"@prettier-ai/dsh-client-ui-session": "^0.1.2-alpha.1",
|
|
76
|
+
"@prettier-ai/dsh-client-ui-sidebar": "^0.1.2-alpha.1",
|
|
77
|
+
"@prettier-ai/dsh-settings": "^0.1.2-alpha.1"
|
|
78
|
+
},
|
|
79
|
+
"files": [
|
|
80
|
+
"lib/index.js",
|
|
81
|
+
"lib/invariant.js",
|
|
82
|
+
"lib/client.js",
|
|
83
|
+
"lib/types/**/*.d.ts"
|
|
84
|
+
],
|
|
85
|
+
"scripts": {
|
|
86
|
+
"bundle": "tsdown",
|
|
87
|
+
"watch": "tsdown --watch"
|
|
88
|
+
}
|
|
89
|
+
}
|