dsh-quick-actions 0.1.0-rc.3

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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +199 -0
  3. package/README.md +199 -0
  4. package/cordis.patch.yml +29 -0
  5. package/lib/client.js +3901 -0
  6. package/lib/client.js.map +1 -0
  7. package/lib/index.js +737 -0
  8. package/lib/types/client/controller.d.ts +207 -0
  9. package/lib/types/client/dsh.d.ts +171 -0
  10. package/lib/types/client/index.d.ts +43 -0
  11. package/lib/types/client/manager/ActionForm.d.ts +20 -0
  12. package/lib/types/client/manager/ActionPanel.d.ts +15 -0
  13. package/lib/types/client/manager/ManagedRow.d.ts +40 -0
  14. package/lib/types/client/manager/ManagerPanel.d.ts +9 -0
  15. package/lib/types/client/manager/press.d.ts +38 -0
  16. package/lib/types/client/manager/search.d.ts +56 -0
  17. package/lib/types/client/manager/status.d.ts +23 -0
  18. package/lib/types/client/modal.d.ts +55 -0
  19. package/lib/types/client/session/ConfirmPanel.d.ts +23 -0
  20. package/lib/types/client/session/availability.d.ts +19 -0
  21. package/lib/types/client/session/execution.d.ts +86 -0
  22. package/lib/types/client/session/guards.d.ts +59 -0
  23. package/lib/types/client/surfaces/ActionFace.d.ts +21 -0
  24. package/lib/types/client/surfaces/ErrorBoundary.d.ts +31 -0
  25. package/lib/types/client/surfaces/QuickActionsSurface.d.ts +17 -0
  26. package/lib/types/client/surfaces/entries.d.ts +27 -0
  27. package/lib/types/client/surfaces/layout.d.ts +49 -0
  28. package/lib/types/client/surfaces/residency.d.ts +65 -0
  29. package/lib/types/host/config.d.ts +18 -0
  30. package/lib/types/host/index.d.ts +38 -0
  31. package/lib/types/host/presets.d.ts +26 -0
  32. package/lib/types/host/settings.d.ts +113 -0
  33. package/lib/types/index.d.ts +35 -0
  34. package/lib/types/locales/index.d.ts +34 -0
  35. package/lib/types/model/catalog.d.ts +63 -0
  36. package/lib/types/model/index.d.ts +13 -0
  37. package/lib/types/model/json.d.ts +11 -0
  38. package/lib/types/model/mutations.d.ts +98 -0
  39. package/lib/types/model/normalize.d.ts +15 -0
  40. package/lib/types/model/projection.d.ts +49 -0
  41. package/lib/types/model/settings.d.ts +48 -0
  42. package/lib/types/model/text.d.ts +28 -0
  43. package/lib/types/model/types.d.ts +89 -0
  44. package/lib/types/model/validation.d.ts +40 -0
  45. package/lib/types/styles/index.d.ts +39 -0
  46. package/lib/types/types.d.ts +11 -0
  47. package/lib/types.js +1 -0
  48. package/package.json +83 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lovvvve
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.en.md ADDED
@@ -0,0 +1,199 @@
1
+ # dsh-quick-actions
2
+
3
+ *中文:[README.md](./README.md)*
4
+
5
+ Global Quick Actions next to every ordinary, session-backed **Resident Composer** in DSH. One press sends a piece of text you wrote in advance.
6
+
7
+ Preset Quick Actions ship with the package and are read-only — you can hide or clone them. Custom Quick Actions are entirely yours. Everything is persisted through DSH's local Settings and survives restarts.
8
+
9
+ ## What it does
10
+
11
+ - **Send Actions**: load a piece of static text into the draft and submit it through the official path. There is exactly one loading path, `setDraft(text)` → `submit()`.
12
+ - **Three layouts**: a ribbon above the input, a bar inside it, or a single launcher opening a searchable panel. Switch at any time.
13
+ - **Per-action send confirmation**, on by default and yours to change.
14
+ - **Text starting with `/` is a valid Command Send Action**, adjudicated by DSH itself.
15
+ - Presets and customs are capped at **50 combined**. At the cap, adding and cloning stop; if an upgrade or a config change pushes existing state past it, **no data is lost** — adding and cloning are simply refused until you are back under it.
16
+
17
+ This release has **no insert action** (insert at the selection, keep the editing context): DSH has not published `insertText`, and this release neither detects nor depends on it. Action text is static — no variables, templates or scripts. Every action is global, with no per-Agent or per-conversation visibility rules and no cross-device sync, import or export. Quick Actions never appear next to a no-session, hero or takeover composer.
18
+
19
+ ## Compatibility
20
+
21
+ | Item | Value |
22
+ |---|---|
23
+ | Verified baseline | DSH core packages at `0.1.5-rc.1`. Note that `dsh --version` on the desktop build prints its dependency-set label, a different number from the core package version |
24
+ | DSH peers | `>=0.1.5-rc.1` |
25
+ | Cordis | `^4.0.2` |
26
+ | Schemastery | `^3.18.2` |
27
+ | React and React DOM (browser side) | `^18.3.1`, supplied by the web shell's module table rather than installed into the profile |
28
+ | DSH UI primitives (browser side) | `>=0.1.5-rc.1`, also supplied by the module table |
29
+ | Platform | `web` profile only |
30
+
31
+ Nothing is capability-detected at install or at runtime, so there is no feature tiering that varies with the DSH version: either the whole plugin installs and runs, or it does not.
32
+
33
+ The floor is the DSH release whose Input contract this plugin reads. **Do not run it against anything older**: `0.1.5-rc.1` renamed `imageIds` to `attachmentIds` in the published snapshot, and this plugin reads the new name.
34
+
35
+ No upper bound is declared, but **that is not a promise of forward compatibility**. Two things to know:
36
+
37
+ - **The rc line does break published contracts.** Between `0.1.2-rc.1` and `0.1.5-rc.1`, the very field this plugin uses as its only send precondition was renamed, and the whole Quick Actions area rendered an error boundary after the upgrade. Every DSH upgrade may need a follow-up release of this plugin; if the area shows an error after one, suspect another contract change and please open an issue.
38
+ - **`>=0.1.5-rc.1` does not match the next prerelease under semver.** A prerelease version only satisfies a comparator with the same major.minor.patch, so `0.1.6-rc.1` does not satisfy `>=0.1.5-rc.1` — and every DSH version published so far is a prerelease. The moment DSH ships a new rc, package managers report an unmet peer dependency even when the plugin is fine. That is semver's rule for prereleases rather than this plugin being picky: if `dsh plugin add` installs it, keep using it, and judge breakage by the point above. (The `Issues with peer dependencies found` note under "What a good install looks like" below has a different cause; the two show up together.)
39
+
40
+ ## Install
41
+
42
+ ```sh
43
+ dsh plugin --profile web add dsh-quick-actions
44
+ ```
45
+
46
+ Then restart the web profile. One package is the whole thing: it carries `dsh.bundle.patch`, which inserts its Host half into the profile, while its `dsh.client` declaration makes the web app load the browser half.
47
+
48
+ ### Local / offline install
49
+
50
+ ```sh
51
+ mkdir -p /tmp/quick-actions
52
+ pnpm --filter dsh-quick-actions pack --pack-destination /tmp/quick-actions
53
+ dsh plugin --profile web add /tmp/quick-actions/dsh-quick-actions-0.1.0-rc.3.tgz
54
+ ```
55
+
56
+ The `--filter` form works from anywhere in the repository; from the package directory itself, `pnpm pack --pack-destination /tmp/quick-actions` is the same thing.
57
+
58
+ Use an **absolute path** for the tarball: `dsh plugin` is a pnpm forwarder and pnpm runs in the profile directory, so a relative path resolves under `<DSH_HOME>/profiles/web/` and fails with `ENOENT`.
59
+
60
+ ### What a good install looks like
61
+
62
+ - `<DSH_HOME>/profiles/web/package.json` gains `dsh-quick-actions` both under `dependencies` and at the end of `dsh.profile.bundles`. Both are maintained by `dsh plugin` — do not hand-edit them.
63
+ - You can check without starting a server:
64
+
65
+ ```sh
66
+ dsh --profile web --dump-config | grep -A1 'id: composer-quick-actions'
67
+ ```
68
+
69
+ You should see `- id: composer-quick-actions` / `name: dsh-quick-actions`. That row takes effect on the **next profile boot**.
70
+
71
+ - pnpm prints `Issues with peer dependencies found`. **That is expected**: DSH's own packages live in DSH's install anchor, where the profile's pnpm cannot see them. Every other third-party DSH plugin in the same profile behaves the same way.
72
+
73
+ ### The install fails with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`
74
+
75
+ The install may end like this, with **not one of the named packages being this plugin**:
76
+
77
+ ```text
78
+ ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION 4 lockfile entries failed verification:
79
+ some-other-plugin@1.2.3 was published at ..., within the minimumReleaseAge cutoff (...)
80
+ ```
81
+
82
+ pnpm enforces a supply-chain policy that rejects dependencies published inside a cooling-off window (24 hours by default), and it checks the **whole profile lockfile** rather than only the package you are adding. So if any plugin already in the profile shipped a release in the last day without an exemption, adding anything at all is refused.
83
+
84
+ To confirm it has nothing to do with this plugin, run a bare `pnpm install` in the profile directory, adding nothing; the same error means exactly that. Three ways out:
85
+
86
+ 1. Pass a flag for this one command, affecting nothing else:
87
+
88
+ ```sh
89
+ dsh plugin --profile web add dsh-quick-actions --config.minimumReleaseAge=0
90
+ ```
91
+
92
+ 2. Wait the window out. Each line of the error gives a publish time and the cutoff; once the newest is 24 hours old the install works unchanged.
93
+ 3. Add each named `name@version` to `minimumReleaseAgeExclude` in `<DSH_HOME>/profiles/web/pnpm-workspace.yaml`, at the cost of giving up that protection for those packages.
94
+
95
+ ## Configuring Preset Quick Actions
96
+
97
+ The preset catalog is two parts in order: the list built into the package, then whatever the Host composition appends through `Config.presets`. That is the only channel for declaring presets — there is no runtime registration API.
98
+
99
+ Put `config` on the plugin's row:
100
+
101
+ ```yaml
102
+ # <DSH_HOME>/profiles/web/cordis.patch.yml
103
+ - id: composer-quick-actions
104
+ config:
105
+ presets:
106
+ - id: run-tests
107
+ label: Run tests
108
+ text: Run the test suite and paste the failures.
109
+ icon: ✅
110
+ - id: add-tests
111
+ label: Add tests
112
+ text: Add tests for that change, failing ones first.
113
+ confirm: false
114
+ ```
115
+
116
+ Field rules:
117
+
118
+ - `id` is required, unique across the catalog and **permanent**. Label, icon and text may change under the same `id`; `confirm` is part of the safety signature, so changing it needs a new `id` — and so does making the text start with `/`, or stop starting with it.
119
+ - `label` and `text` are required; `icon` and `confirm` are optional, and `confirm` defaults to `true`.
120
+ - An invalid preset (a missing field, a duplicate `id`, a catalog over 50 entries) makes **plugin loading fail loudly** and lists every problem at once, rather than truncating silently.
121
+
122
+ Users can hide or clone a preset but never edit or delete it; a clone becomes an ordinary Custom Quick Action.
123
+
124
+ ## Three layouts
125
+
126
+ Layout is a global persisted setting, switched in the management panel:
127
+
128
+ | Value | Name | Where |
129
+ |---|---|---|
130
+ | `ribbon` (default) | Action ribbon | One row above the input, matching its width |
131
+ | `bar` | Action bar | One row inside the input; whatever does not fit folds into "more" |
132
+ | `launcher` | Single launcher | One entry button opening a searchable panel |
133
+
134
+ `bar` and `launcher` share the same searchable panel, and the search matches labels and texts only. The management panel is where you reorder, hide, restore and clone presets, create, edit, enable and delete custom actions, and switch layout.
135
+
136
+ ## Command Send Action
137
+
138
+ Static text whose first non-whitespace character is `/` is marked as a command.
139
+
140
+ - It travels **exactly the same path** as any other Send Action, and the command is adjudicated by DSH itself; this plugin never parses or rewrites command semantics.
141
+ - Confirmation is on by default and **can be turned off**. The `confirm` you set is never rewritten.
142
+ - With confirmation on, the panel shows precisely what will be submitted. **The native candidate menu you get when typing `/` in the composer does not appear here**, so adjudication may differ from typing the same command by hand.
143
+ - With confirmation off, the command is submitted in one press with no preview.
144
+ - The management form warns you when text becomes a command, but locks no control.
145
+
146
+ ## Settings paths
147
+
148
+ User data lives in `<DSH_HOME>/settings.yaml` (`~/.dsh` when `DSH_HOME` is unset):
149
+
150
+ - `composer-quick-actions` — the **only** persisted namespace: layout, custom actions, the shared order and preset differences.
151
+ - `composer-quick-actions-catalog` — the preset catalog. Read-only, never written to the user layer, so it does **not** appear in that file.
152
+
153
+ The Host is the single validation authority and normalizes stored data idempotently at boot. Every change made in the UI carries an expected revision; on a conflict the panel refreshes to the latest state and asks you to confirm again, never silently overwriting someone else's write. Data written by a higher `schemaVersion` is kept as-is, so a downgrade round-trip loses nothing.
154
+
155
+ ## Upgrade, downgrade and uninstall
156
+
157
+ **Upgrade / downgrade**:
158
+
159
+ ```sh
160
+ dsh plugin --profile web add dsh-quick-actions@<version>
161
+ ```
162
+
163
+ With a local tarball, `add` the tarball of the version you want. Restart the profile afterwards. Re-adding the same version is idempotent.
164
+
165
+ Cross-version data compatibility is the Host's job: new presets are appended to the end of the existing order and nothing stored is rewritten.
166
+
167
+ **Uninstall**:
168
+
169
+ ```sh
170
+ dsh plugin --profile web remove dsh-quick-actions
171
+ ```
172
+
173
+ Both the dependency and the layer in `dsh.profile.bundles` go away. After a profile restart the actions are gone.
174
+
175
+ **Full manual cleanup** (uninstalling does none of this, because a reinstall should restore your actions):
176
+
177
+ 1. Delete the `composer-quick-actions` section from `<DSH_HOME>/settings.yaml` — the only place user data lives.
178
+ 2. Remove any entry you added for this plugin from `<DSH_HOME>/profiles/web/pnpm-workspace.yaml`.
179
+ 3. Delete any `config` you wrote for `composer-quick-actions` in the profile's `cordis.patch.yml`.
180
+ 4. Restart the profile.
181
+
182
+ ## Development
183
+
184
+ ```sh
185
+ pnpm install
186
+ pnpm build # Host ESM plus the single-file lazy-CJS Client
187
+ pnpm watch:client # rebuild the Client bundle only
188
+ pnpm test
189
+ pnpm typecheck
190
+ pnpm lint
191
+ ```
192
+
193
+ Output: the Host is `lib/index.js` and `lib/types.js` (plain Node ESM); the Client is `lib/client.js` plus a sourcemap, a browser-only single-file lazy-CJS bundle; types are `lib/types/**/*.d.ts`, declarations only.
194
+
195
+ `pnpm watch:client` is **not** DSH GUI HMR. For a change to reach a running page, three things must hold: the profile is loading the checkout you are watching (an offline install loads a copy of the tarball), that checkout's watcher is running and has produced one complete build, and the page has refetched the new output. The Client artifact is published atomically, so a failed watch build keeps the last successful one and the page may still be running old code.
196
+
197
+ ## License
198
+
199
+ MIT
package/README.md ADDED
@@ -0,0 +1,199 @@
1
+ # dsh-quick-actions
2
+
3
+ *English: [README.en.md](./README.en.md)*
4
+
5
+ 在 DSH 每个常规、由会话支持的**常驻消息编辑器(Resident Composer)**旁提供全局快捷动作。按一下按钮,把预先写好的一段文本发出去。
6
+
7
+ 预置动作(Preset Quick Action)随包提供、只读,你可以隐藏或克隆它;自定义动作(Custom Quick Action)完全归你。所有数据经 DSH 本地 Settings 持久化,跨重启保留。
8
+
9
+ ## 能做什么
10
+
11
+ - **发送动作**:把一段静态文本装载进草稿并按官方路径提交,装载路径只有一条 `setDraft(text)` → `submit()`。
12
+ - **三种布局**:输入框上方的动作带、输入框内的操作栏、单入口的可搜索面板,随时切换。
13
+ - **每个动作可单独设置发送确认**,默认开启,之后由你决定。
14
+ - **`/` 开头的文本是合法的命令发送动作**,交给 DSH 官方裁决。
15
+ - 预置与自定义**合计上限 50 个**。达到上限后不能再新增或克隆;若升级或配置变化把既有状态推过上限,**已有数据一个都不会丢**,只是在回到上限以内之前禁止新增和克隆。
16
+
17
+ 本版**不提供插入动作**(按选区插入、保留编辑上下文):DSH 尚未公开 `insertText`,本版既不检测也不依赖它。动作文本是静态的,没有变量、模板或脚本。所有动作全局生效,暂无按 Agent 或按对话的可见性规则,也没有跨设备同步与导入导出。快捷动作不会出现在 no-session、hero 或 takeover 消息编辑器旁。
18
+
19
+ ## 兼容性
20
+
21
+ | 项目 | 值 |
22
+ |---|---|
23
+ | 验证基线 | DSH 核心包 `0.1.5-rc.1`。桌面端 `dsh --version` 打印的是依赖集标签,与核心包版本不是同一个数字 |
24
+ | DSH peer | `>=0.1.5-rc.1` |
25
+ | Cordis | `^4.0.2` |
26
+ | Schemastery | `^3.18.2` |
27
+ | React 与 React DOM(浏览器侧) | `^18.3.1`,由 web shell 的模块表提供,不从 profile 安装 |
28
+ | DSH UI primitives(浏览器侧) | `>=0.1.5-rc.1`,同样由模块表提供 |
29
+ | 平台 | 只支持 `web` profile |
30
+
31
+ 安装与运行都不检测 DSH 能力,因此不存在随版本变化的功能分档:要么整个插件能装能跑,要么装不上。
32
+
33
+ 下界取的是本插件读取其 Input 契约的那个 DSH 版本。**不要在更低版本上使用**:`0.1.5-rc.1` 把公开快照里的 `imageIds` 改名为 `attachmentIds`,本插件按新名读取。
34
+
35
+ 上界不设,但**这不等于向后兼容有保障**,两点需要知道:
36
+
37
+ - **rc 阶段会破坏公开契约。** `0.1.2-rc.1` 到 `0.1.5-rc.1` 之间,被本插件用作唯一发送判据的那个字段就被改了名,升级 DSH 后整个快捷动作区域会显示错误边界。每次 DSH 升级都可能需要本插件跟一版;升级后若该区域出错,多半又是契约变更,请提 issue。
38
+ - **`>=0.1.5-rc.1` 在 semver 里匹配不到下一个预发布版本。** 预发布版本只满足「主次修订号完全相同」的比较符,因此 `0.1.6-rc.1` 不满足 `>=0.1.5-rc.1`;而 DSH 至今发布的每个版本都是预发布。DSH 一旦发出新的 rc,包管理器就会报未满足的 peer 依赖,即使插件本身没问题。这是 semver 对预发布的规定,不是本插件挑版本——`dsh plugin add` 装得上就可以继续用,出错时按上一条判断。(下面「装好之后」里那条 `Issues with peer dependencies found` 说的是另一个原因,两者会一起出现。)
39
+
40
+ ## 安装
41
+
42
+ ```sh
43
+ dsh plugin --profile web add dsh-quick-actions
44
+ ```
45
+
46
+ 然后重启 web profile。一个包就是全部:它自带 `dsh.bundle.patch` 把自己的 Host 半边插进 profile,`dsh.client` 声明让 web 端加载浏览器半边。
47
+
48
+ ### 本地 / 离线安装
49
+
50
+ ```sh
51
+ mkdir -p /tmp/quick-actions
52
+ pnpm --filter dsh-quick-actions pack --pack-destination /tmp/quick-actions
53
+ dsh plugin --profile web add /tmp/quick-actions/dsh-quick-actions-0.1.0-rc.3.tgz
54
+ ```
55
+
56
+ 上面的 `--filter` 形式在仓库任意位置都能用;如果你已经在包目录里,`pnpm pack --pack-destination /tmp/quick-actions` 即可。
57
+
58
+ tarball 路径要用**绝对路径**:`dsh plugin` 是 pnpm 的转发器,pnpm 在 profile 目录里运行,相对路径会解析到 `<DSH_HOME>/profiles/web/` 下并以 `ENOENT` 失败。
59
+
60
+ ### 装好之后
61
+
62
+ - `<DSH_HOME>/profiles/web/package.json` 的 `dependencies` 与 `dsh.profile.bundles` 末尾都会多出 `dsh-quick-actions`。这两处由 `dsh plugin` 维护,不要手工编辑。
63
+ - 不启动服务器也能检查:
64
+
65
+ ```sh
66
+ dsh --profile web --dump-config | grep -A1 'id: composer-quick-actions'
67
+ ```
68
+
69
+ 应当看到 `- id: composer-quick-actions` / `name: dsh-quick-actions`。这条 row 在**下一次 profile 启动**时生效。
70
+
71
+ - pnpm 会打印 `Issues with peer dependencies found`。**这是正常的**:DSH 核心包装在 DSH 自己的安装锚点里,profile 的 pnpm 看不到它们。同一 profile 里其它第三方 DSH 插件也是同样表现。
72
+
73
+ ### 安装报 `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`
74
+
75
+ 安装可能以这样的错误结束,而**被点名的包一个都不是本插件**:
76
+
77
+ ```text
78
+ ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION 4 lockfile entries failed verification:
79
+ some-other-plugin@1.2.3 was published at ..., within the minimumReleaseAge cutoff (...)
80
+ ```
81
+
82
+ pnpm 有一条供应链策略:拒绝发布时间在冷却窗口内(默认 24 小时)的依赖。它校验的是**整个 profile 的 lockfile**,不只是你这次要装的包——所以只要 profile 里任何一个已装插件在最近一天发过新版且没拿到豁免,装任何东西都会被拦下。
83
+
84
+ 想确认与本插件无关,在 profile 目录里单跑一次 `pnpm install`,什么都不加;报同样的错就说明如此。三种处理方式:
85
+
86
+ 1. 给这一次命令加个标志,只影响本次:
87
+
88
+ ```sh
89
+ dsh plugin --profile web add dsh-quick-actions --config.minimumReleaseAge=0
90
+ ```
91
+
92
+ 2. 等冷却期过去。错误信息里写了每一条的发布时间与截止时间,等最晚的那个满 24 小时即可。
93
+ 3. 把被点名的 `名字@版本` 逐条加进 `<DSH_HOME>/profiles/web/pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude`,代价是对这些包放弃这层保护。
94
+
95
+ ## 配置预置动作
96
+
97
+ 预置目录由两部分拼成:先是随包内置的清单,然后是 Host composition 在 `Config.presets` 里追加的条目。`Config.presets` 是预置的唯一声明通道,没有运行时注册 API。
98
+
99
+ 在插件那条 row 上写 `config`:
100
+
101
+ ```yaml
102
+ # <DSH_HOME>/profiles/web/cordis.patch.yml
103
+ - id: composer-quick-actions
104
+ config:
105
+ presets:
106
+ - id: run-tests
107
+ label: 跑测试
108
+ text: 把测试跑一遍,把失败项贴出来。
109
+ icon: ✅
110
+ - id: add-tests
111
+ label: 补测试
112
+ text: 给刚才的改动补上测试,先写失败用例。
113
+ confirm: false
114
+ ```
115
+
116
+ 字段规则:
117
+
118
+ - `id` 必填、全目录唯一且**永久**。标签、图标、文本可以在同一个 `id` 下改;`confirm` 属于安全行为签名,要改就得换新 `id`——把文本改成以 `/` 开头(或改掉这一点)同样算。
119
+ - `label`、`text` 必填;`icon`、`confirm` 可选,`confirm` 默认 `true`。
120
+ - 预置无效(缺字段、`id` 重复、目录超过 50 条)会让**插件加载响亮失败**并一次列出所有问题,而不是静默截断。
121
+
122
+ 用户对预置只能隐藏或克隆,不能编辑或删除;克隆出来的是一条普通的自定义动作。
123
+
124
+ ## 三种布局
125
+
126
+ 布局是全局持久化设置,在管理面板里切换:
127
+
128
+ | 值 | 名称 | 位置 |
129
+ |---|---|---|
130
+ | `ribbon`(默认) | 上方动作带 | 输入框上方一行,与输入框等宽 |
131
+ | `bar` | 下方操作栏 | 输入框内部下方一行,装不下的折进「更多」 |
132
+ | `launcher` | 单入口面板 | 一个入口按钮,点开可搜索的动作面板 |
133
+
134
+ `bar` 与 `launcher` 共用同一个可搜索面板,搜索只匹配标签和文本。管理面板里可以给预置排序、隐藏、恢复、克隆,增删改自定义动作并启停它们,以及切换布局。
135
+
136
+ ## 命令发送动作(Command Send Action)
137
+
138
+ 首个非空白字符是 `/` 的静态文本会被标记为「命令」。
139
+
140
+ - 它与普通发送动作走**完全相同**的一条路径,命令一律交给 DSH 官方裁决;本插件不解析、不改写命令语义。
141
+ - 确认默认开启,**可以关闭**。你设定的 `confirm` 不会被改写。
142
+ - 确认开启时,面板展示的就是最终提交内容。**但这里不会出现你在原生输入框敲 `/` 时的候选菜单**,因此裁决结果可能与逐字输入同一条命令时不同。
143
+ - 确认关闭时,命令一键提交、没有预览。
144
+ - 管理表单在文本成为命令时给出警示,但不锁定任何控件。
145
+
146
+ ## Settings 路径
147
+
148
+ 用户数据落在 `<DSH_HOME>/settings.yaml`(`DSH_HOME` 未设置时是 `~/.dsh`):
149
+
150
+ - `composer-quick-actions` — **唯一的持久化命名空间**,存放布局、自定义动作、统一顺序和预置差异。
151
+ - `composer-quick-actions-catalog` — 预置目录,只读,不写用户层,因此**不会**出现在这个文件里。
152
+
153
+ Host 是校验的唯一权威,启动时按当前目录对存放的数据做一次幂等规范化。界面的每次修改都带上预期 revision;发生冲突时会刷新到最新状态并请你确认后重试,绝不静默覆盖别人的写入。更高 `schemaVersion` 写下的数据原样保留,因此降级往返无损。
154
+
155
+ ## 升级、降级与卸载
156
+
157
+ **升级 / 降级**:
158
+
159
+ ```sh
160
+ dsh plugin --profile web add dsh-quick-actions@<version>
161
+ ```
162
+
163
+ 本地 tarball 则 `add` 指向目标版本的那个 tarball。之后重启 profile。重复 `add` 同一版本是幂等的。
164
+
165
+ 跨版本的数据兼容由 Host 负责:新增预置只追加到既有顺序末尾,不改写任何已存数据。
166
+
167
+ **卸载**:
168
+
169
+ ```sh
170
+ dsh plugin --profile web remove dsh-quick-actions
171
+ ```
172
+
173
+ 依赖与 `dsh.profile.bundles` 里的那一层会同时去掉,重启 profile 后动作不再出现。
174
+
175
+ **手工彻底清理**(卸载不做这些,因为重装应当恢复你的动作):
176
+
177
+ 1. 从 `<DSH_HOME>/settings.yaml` 删掉 `composer-quick-actions` section,这是唯一保存用户数据的地方。
178
+ 2. 如果 `<DSH_HOME>/profiles/web/pnpm-workspace.yaml` 里有为本插件加过的条目,一并删掉。
179
+ 3. 如果在 profile 的 `cordis.patch.yml` 里给 `composer-quick-actions` 写过 `config`,把那段删掉。
180
+ 4. 重启 profile。
181
+
182
+ ## 开发
183
+
184
+ ```sh
185
+ pnpm install
186
+ pnpm build # Host ESM + Client 单文件 lazy-CJS
187
+ pnpm watch:client # 只重建 Client bundle
188
+ pnpm test
189
+ pnpm typecheck
190
+ pnpm lint
191
+ ```
192
+
193
+ 产物:Host 为 `lib/index.js` 与 `lib/types.js`(标准 Node ESM);Client 为 `lib/client.js` 加 sourcemap,browser-only 单文件 lazy-CJS;类型为 `lib/types/**/*.d.ts`,只有声明。
194
+
195
+ `pnpm watch:client` **不等于** DSH GUI 的 HMR。要让改动落到运行中的页面,先确认三件事:被 profile 实际加载的是你正在 watch 的那个 checkout(离线安装装的是 tarball 的副本);该 checkout 的 watcher 正在跑且已成功产出过一次;页面重新拉取了新产物。Client 产物是原子发布的,watch 构建失败时保留上一次成功的产物,所以页面可能仍在跑旧代码。
196
+
197
+ ## 许可证
198
+
199
+ MIT
@@ -0,0 +1,29 @@
1
+ # The `dsh.bundle.patch` layer of this package.
2
+ #
3
+ # `dsh plugin --profile web add dsh-quick-actions` installs this package as a profile
4
+ # dependency; because the manifest declares `dsh.bundle`, the CLI appends the package to
5
+ # `dsh.profile.bundles`, and profile boot then applies this layer over the bundles ahead of
6
+ # it. The single `insert` mounts this package's own Host half — `name` points at this very
7
+ # package — while its `dsh.client` declaration is what makes the web app load `./client` as
8
+ # the browser half. No profile file needs editing by hand.
9
+ #
10
+ # One package carries both halves and this patch, which is what every other third-party DSH
11
+ # plugin does (ticket 28). An earlier design split the patch into a second `-bundle` package;
12
+ # that only made an offline install need two tarballs plus a profile `overrides` entry,
13
+ # because a direct dependency does not satisfy a transitive one.
14
+ #
15
+ # `id` is the loader entry id and is part of the installed identity: it is what `cordis`
16
+ # reports, what a `disabled` expression in a later layer would target, and what an aggregate
17
+ # bundle would collide with. It stays `composer-quick-actions` even though the package is
18
+ # named `dsh-quick-actions` — the two are different identity axes, and the id matches the
19
+ # domain term (Composer Quick Actions) and the Settings namespaces (spec 19).
20
+ #
21
+ # The plugin takes no required config. To declare additional Preset Quick Actions, add a
22
+ # `config.presets` block for the `composer-quick-actions` id in the PROFILE's own patch
23
+ # layer — `<DSH_HOME>/profiles/<name>/cordis.patch.yml`, which is applied after every bundle
24
+ # layer. Never edit this file in an installed `node_modules`: an install replaces it. An
25
+ # invalid preset there fails plugin loading loudly rather than shipping a partial catalog.
26
+ # The readme has a worked example.
27
+ - insert:
28
+ - id: composer-quick-actions
29
+ name: dsh-quick-actions