dsh-at-menu 0.0.0-stage → 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-at-menu contributors
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,100 @@
1
+ # dsh-at-menu
2
+
3
+ [中文](README.md) | **English**
4
+
5
+ When the `@` reference menu opens, a row of category tabs appears on top of it: pick a tab to see only
6
+ that category instead of scrolling through one mixed list.
7
+
8
+ ## Categories
9
+
10
+ Only the three kinds the DSH conversation UI already has data for are built in:
11
+
12
+ | Category | Source |
13
+ | --- | --- |
14
+ | Workspace files | The workspace file-reference API; files and folders share one category, and a folder row drills into the directory with the trailing arrow (or Tab), with breadcrumbs to go back up |
15
+ | Past sessions | Plain sessions from the session-reference candidates |
16
+ | Subagent sessions | The rows marked as subagents in the same candidate list |
17
+
18
+ Skills, plugins, saved prompts, sidebar references and so on are **not** built in: each plugin
19
+ registers its own source through
20
+ `ctx.inputTriggers.registerSource({ trigger: '@', name: 'name', candidates, onPick })`,
21
+ and the panel turns every registered source into a tab — `name` is the tab label.
22
+
23
+ ## Install
24
+
25
+ ```sh
26
+ dsh plugin --profile desktop add github:taoziliyouchong/dsh-at-menu
27
+ ```
28
+
29
+ Once published to npm, this also works:
30
+
31
+ ```sh
32
+ dsh plugin --profile desktop add dsh-at-menu
33
+ ```
34
+
35
+ Restart DSH afterwards. Replace `desktop` with your own profile name if you use another one.
36
+
37
+ Requirements: DSH 0.2.1 or later, desktop app or `dsh web` (needs the @ menu of the conversation composer; verified on 0.2.2-rc.1).
38
+ Requires DSH >= 0.2.1-alpha.3; verified on 0.2.1-alpha.3 and 0.2.2-rc.1, later versions untested.
39
+
40
+ ## Works alongside the built-in @ menu
41
+
42
+ Keep the built-in `ui-reference` enabled; the two run together. It owns `source "reference"`, which
43
+ handles two things this plugin does not:
44
+
45
+ - file reference cards created by dropping files onto the composer (or the add-file button) are turned
46
+ into text by it — without it, sending fails with
47
+ `slash: no serializer for reference source "reference"`;
48
+ - the decoration and click-to-open on `@path` mentions in past messages.
49
+
50
+ This panel only takes over the look of the @ menu: the built-in's candidate group is not shown here,
51
+ and the keyboard highlight is pushed back to a visible category when it lands on it.
52
+
53
+ ## How it works
54
+
55
+ - The panel mounts at the list slot `conversation.input.overlay`, the same seat as the built-in menu;
56
+ an injected style hides the built-in menu only while the @ menu is open
57
+ (`body[data-dsh-at-open] [data-trigger-menu]`), so the `/` slash menu keeps its native look.
58
+ - Data, keyboard handling (up/down, Enter, Esc) and insertion stay owned by the built-in controller;
59
+ the panel only subscribes to its menu store and feeds pick / hover / dismiss back.
60
+ - Mentions go into the draft as plain text (`@path`, `@[title](dsh-session:…)`), and the existing
61
+ text-parsing chain on the host side keeps working.
62
+ - No network access, nothing uploaded.
63
+
64
+ ## Known limits
65
+
66
+ - With the built-in `ui-reference` enabled, its merged "files + sessions" group is not shown in this panel (the keyboard skips it too); use the built-in menu for that merged view.
67
+ - Tabs only show sources registered in `CATEGORY_SOURCES`; a plugin that registers a new source name
68
+ needs that line in `src/entry.jsx` edited before its tab shows up.
69
+ - This plugin only changes the look and grouping of the @ menu; it does not change the insertion format.
70
+
71
+ ## Development
72
+
73
+ ```sh
74
+ npm install
75
+ npm run build:client # regenerate lib/client.js from src/entry.jsx
76
+ npm run check:client # verify the committed artifact matches the source
77
+ npm run check # syntax
78
+ npm run smoke # structure / bundle declaration / host / artifact / companion
79
+ ```
80
+
81
+ `lib/client.js` is a build artifact committed to the repository: installing from GitHub does not run
82
+ a build, and without it the UI does not load. Keep `react` and `react/jsx-runtime` external (the DSH
83
+ client module table provides them); the `id` inside the `window.__ModuleLoader__.load({ id, factory })`
84
+ envelope must equal the package name.
85
+
86
+ Source layout:
87
+
88
+ - `src/entry.jsx` — the browser half (panel, tabs, source registration)
89
+ - `index.js` — the host half (no host behavior; exists so the plugin loader can load the package)
90
+
91
+ ## Feedback
92
+
93
+ - Open an issue: https://github.com/taoziliyouchong/dsh-at-menu/issues
94
+ - Or reach me on QQ: **2171960697** (mention which plugin you installed when adding the contact).
95
+
96
+ Please include: DSH version, plugin version, the exact error text, and a screenshot.
97
+
98
+ ## License
99
+
100
+ MIT
package/README.md CHANGED
@@ -1,3 +1,95 @@
1
- # Temporary Holding Version
1
+ # dsh-at-menu
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **中文** | [English](README.en.md)
4
+
5
+ 按 `@` 弹出的引用菜单顶部多一排类别标签:点标签只看该类候选,不用一直往下滚动找组。
6
+
7
+ ## 有什么类别
8
+
9
+ 只内置 DSH 会话界面本来就有数据的三类:
10
+
11
+ | 类别 | 数据来源 |
12
+ | --- | --- |
13
+ | 工作区文件 | 会话工作区的文件引用接口;文件与文件夹同列一类,文件夹行尾部箭头(或 Tab)进入目录,面包屑点上级 |
14
+ | 历史会话 | 会话引用候选里的普通会话 |
15
+ | 子代理会话 | 同一份候选里带子代理标记的行 |
16
+
17
+ 技能、插件、常用提示词、侧栏引用等类别**不由本插件内置**:它们由各自的插件通过
18
+ `ctx.inputTriggers.registerSource({ trigger: '@', name: '类别名', candidates, onPick })`
19
+ 注册到宿主,面板会把注册过的源显示成类别标签——`name` 就是标签文字,装得越多标签越多。
20
+
21
+ ## 安装
22
+
23
+ ```sh
24
+ dsh plugin --profile desktop add github:taoziliyouchong/dsh-at-menu
25
+ ```
26
+
27
+ 发布到 npm 之后也可以:
28
+
29
+ ```sh
30
+ dsh plugin --profile desktop add dsh-at-menu
31
+ ```
32
+
33
+ 装完重启 DSH。用别的 profile 就把 `desktop` 换成你的 profile 名。
34
+
35
+ 要求:DSH 0.2.1 及以上的桌面端或 `dsh web`(需要会话输入框的 @ 菜单;验证版本 0.2.2-rc.1)。
36
+ 要求 DSH >= 0.2.1-alpha.3;实测 0.2.1-alpha.3、0.2.2-rc.1,更高版本未验证。
37
+
38
+ ## 与内置 @ 菜单共存
39
+
40
+ 内置的 `ui-reference` 不用关,两者同时启用。它提供 `source "reference"`,管两件本插件不做的事:
41
+
42
+ - 往输入框拖文件、或点「添加文件」时生成的文件引用卡片,由它转成文字;它不在,发送会报
43
+ `slash: no serializer for reference source "reference"`;
44
+ - 历史消息里 `@路径` 的装饰样式和点击打开。
45
+
46
+ 本插件的面板只接管 @ 菜单的外观:内置那一组候选不进面板,键盘高亮落到它时会被推回可见类别。
47
+ 两边同时启用不会出现重复候选。
48
+
49
+ ## 怎么工作
50
+
51
+ - 面板挂在 list 槽 `conversation.input.overlay` 上,与内置菜单同一个座位;只在 @ 菜单打开期间
52
+ 用一条注入样式隐藏内置菜单(`body[data-dsh-at-open] [data-trigger-menu]`),`/` 斜杠菜单保持内置外观。
53
+ - 候选数据、键盘(上下 / 回车 / Esc)、插入动作仍由内置 controller 拥有;面板只订阅它的
54
+ menu store,再把 pick / hover / dismiss 回投回去。
55
+ - 引用以纯文本落进草稿(`@路径`、`@[标题](dsh-session:…)`),宿主侧现有的文本解析链照旧工作。
56
+ - 不联网、不上传任何内容。
57
+
58
+ ## 已知限制
59
+
60
+ - 内置 `ui-reference` 的「文件+会话」混合候选组不显示在本面板里(键盘也会跳过它);要看那组混合视图得用内置菜单。
61
+ - 类别标签只显示 `CATEGORY_SOURCES` 里登记过的源;新插件注册了新名字的源,要改 `src/entry.jsx`
62
+ 里那一行才会出标签。
63
+ - 只改 @ 菜单的外观与分组,不改变草稿的插入格式。
64
+
65
+ ## 开发
66
+
67
+ ```sh
68
+ npm install
69
+ npm run build:client # 从 src/entry.jsx 重新生成 lib/client.js
70
+ npm run check:client # 已提交产物与源码一致
71
+ npm run check # 语法
72
+ npm run smoke # 结构 / 组合声明 / 宿主 / 产物 / 伴随插件 五关
73
+ ```
74
+
75
+ `lib/client.js` 是提交进仓库的构建产物:从 GitHub 安装时不跑构建,缺了它界面不加载。
76
+ 打包要求:`react`、`react/jsx-runtime` 保持 external(由 DSH 客户端模块表提供);
77
+ 产物外壳 `window.__ModuleLoader__.load({ id, factory })` 里的 `id` 必须等于包名。
78
+
79
+ 源码只有两处:
80
+
81
+ - `src/entry.jsx` —— 浏览器半边(面板、类别标签、源注册)
82
+ - `index.js` —— 宿主半边(本包没有宿主行为,只为被插件系统加载)
83
+
84
+ ## 反馈
85
+
86
+ 插件有问题,按这个顺序:
87
+
88
+ 1. 开 Issue:https://github.com/taoziliyouchong/dsh-at-menu/issues —— 能留痕、能搜历史;
89
+ 2. 急着问或不想开 Issue,QQ 号:**2171960697**(加好友请注明装的是哪个插件)。
90
+
91
+ 反馈时带上:DSH 版本、插件版本、报错原文、截图。
92
+
93
+ ## 许可
94
+
95
+ MIT
@@ -0,0 +1,4 @@
1
+ # dsh-at-menu:一个插件行,浏览器半边由 package.json 的 dsh.client 声明发现。
2
+ - insert:
3
+ - id: dsh-at-menu
4
+ name: dsh-at-menu
package/index.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * dsh-at-menu 宿主半边:无宿主行为。
3
+ * 面板本体在浏览器半边(exports["./client"]),由 package.json 的 dsh.client 声明发现。
4
+ */
5
+
6
+ /** Cordis 插件名。 */
7
+ export const name = 'dsh-at-menu'
8
+
9
+ /** 宿主插件体——本包只出界面。 */
10
+ export function apply() {}
11
+
12
+ /**
13
+ * 需要的服务:一个都不需要。
14
+ * 显式声明空数组,免得宿主侧「inject 声明完整」的检查把它当成没写 inject。
15
+ */
16
+ export const inject = []
package/invariant.js ADDED
@@ -0,0 +1,10 @@
1
+ const PACKAGE_NAME = 'dsh-at-menu'
2
+
3
+ /** Cordis companion plugin name. */
4
+ export const name = 'dsh-at-menu-invariant'
5
+ /** Service required before the companion can reserve package ownership. */
6
+ export const inject = ['invariants']
7
+
8
+ const install = () => {}
9
+
10
+ export const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))