dsh-graft-plugin 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -5
- package/README.zh-CN.md +218 -0
- package/assets/icon.png +0 -0
- package/package.json +4 -2
- package/src/client.js +16 -9
package/README.md
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="assets/banner-dark.png">
|
|
3
|
+
<img alt="graft" src="assets/banner-light.png" width="1012">
|
|
4
|
+
</picture>
|
|
5
|
+
|
|
6
|
+
<br>
|
|
7
|
+
|
|
1
8
|
# dsh-graft-plugin
|
|
2
9
|
|
|
10
|
+
English | [中文](README.zh-CN.md)
|
|
11
|
+
|
|
3
12
|
      
|
|
4
13
|
|
|
5
14
|
A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that puts [graft](https://github.com/trailhq/Graft) — a prebuilt graph of every symbol, its `file:line` span, and who calls what — in front of both you and the model.
|
|
6
15
|
|
|
7
16
|
It does four things:
|
|
8
17
|
|
|
9
|
-
- **A chip in the composer** naming the graft index the current session is actually serving, whether it still matches the code, and how many tokens graft has saved in that repo.
|
|
10
|
-
- **Five tools for the model** — `graft_ask`, `graft_grep`, `graft_callers`, `graft_skeleton`, `graft_map` — resolved per session, so one dsh can serve several workspaces at once.
|
|
18
|
+
- **A chip in the composer** naming the graft index the current session is actually serving, whether it still matches the code, and how many tokens graft has saved in that repo. Its card carries a **Build** button — rebuild the index, or create the first one.
|
|
19
|
+
- **Five tools for the model** — `graft_ask`, `graft_grep`, `graft_callers`, `graft_skeleton`, `graft_map` — resolved per session, so one dsh can serve several workspaces at once, git worktrees included, each with its own graph.
|
|
11
20
|
- **`/graft`** to build or rebuild the index, and **auto-rebuild** after the model edits files.
|
|
12
21
|
- **A `graft viz` button** that opens the graph in dsh's built-in right sidebar (0.1.5+), in [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) if you still run it, and in a browser tab as the last resort.
|
|
13
22
|
|
|
@@ -101,6 +110,14 @@ Hovering (or clicking) opens a card with the resolved root, node and edge counts
|
|
|
101
110
|
|
|
102
111
|

|
|
103
112
|
|
|
113
|
+
The card's header carries a **Build** button beside the status pill. In a repo that already has an index it runs the same rebuild the auto-rebuild runs — graft's own sync — and holds "Building…" until the pill reads *in sync*, giving up after two minutes and showing the reason. In a workspace with no index yet, Build first asks in dsh's own dialog ("Build graft index?" — Cancel / Build index; Cancel, Escape or clicking outside builds nothing), then runs a plain offline `graft build`, which writes a `graft/` directory there.
|
|
114
|
+
|
|
115
|
+
While a `graft_*` tool is running, the chip's dot blinks violet.
|
|
116
|
+
|
|
117
|
+
Chip, card and viz tab are painted with dsh's own `--dsw-*` theme variables, so they follow the active theme — including theme plugins.
|
|
118
|
+
|
|
119
|
+
A linked git worktree gets its own graph, never the main checkout's: the card and the viz bar name the main checkout it belongs to (`git worktree of <repo>`). With no graph yet, `/graft` in the worktree seeds the first one from it.
|
|
120
|
+
|
|
104
121
|
The root is resolved from **the session's own workspace**, not from wherever dsh was launched. That is the whole reason this exists rather than the `graft mcp` server: `graft mcp` resolves its repo once, from its own working directory at startup, and nothing can re-point it afterwards. Launched from a home directory it answers *"no graph found"* for every workspace you open.
|
|
105
122
|
|
|
106
123
|
### The visualiser
|
|
@@ -146,8 +163,8 @@ All optional, all on the plugin's row in your profile's `cordis.patch.yml`:
|
|
|
146
163
|
cwd: 'C:/path/to/repo' # pin to one repo instead of resolving per session
|
|
147
164
|
tools: false # drop the graft_* tools, keep the chip
|
|
148
165
|
command: false # drop /graft
|
|
149
|
-
promptSection: false # stop telling the model to
|
|
150
|
-
autoBuild: false # stop rebuilding after edits
|
|
166
|
+
promptSection: false # stop telling the model to use graft
|
|
167
|
+
autoBuild: false # stop rebuilding after edits (the card's Build button still works)
|
|
151
168
|
```
|
|
152
169
|
|
|
153
170
|
## Requirements
|
|
@@ -161,7 +178,7 @@ All optional, all on the plugin's row in your profile's `cordis.patch.yml`:
|
|
|
161
178
|
| `0.2.0-rc.2` | needs plugin `0.2.1`+ — earlier releases fail to activate (see Troubleshooting) |
|
|
162
179
|
|
|
163
180
|
- Node 22+
|
|
164
|
-
- the `graft` CLI on PATH (`npm install -g @nanonets/graft`)
|
|
181
|
+
- the `graft` CLI on PATH (`npm install -g @nanonets/graft`). A bun global install (`bun add -g @nanonets/graft`) is detected too, via `$BUN_INSTALL` or `~/.bun`.
|
|
165
182
|
|
|
166
183
|
The client bundle requires only `react`, which is why it survives the dsh `0.1.5-rc.2` client-package removals that broke several neighbouring plugins.
|
|
167
184
|
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="assets/banner-dark.png">
|
|
3
|
+
<img alt="graft" src="assets/banner-light.png" width="1012">
|
|
4
|
+
</picture>
|
|
5
|
+
|
|
6
|
+
<br>
|
|
7
|
+
|
|
8
|
+
# dsh-graft-plugin
|
|
9
|
+
|
|
10
|
+
[English](README.md) | 中文
|
|
11
|
+
|
|
12
|
+
      
|
|
13
|
+
|
|
14
|
+
一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件,把 [graft](https://github.com/trailhq/Graft)——一张预先构建的符号图(每个符号的 `file:line` 位置、谁调用了谁)——同时摆到你和模型面前。
|
|
15
|
+
|
|
16
|
+
它做四件事:
|
|
17
|
+
|
|
18
|
+
- **输入框里的徽章(chip)**:说出当前会话实际在用哪个 graft 索引、它是否还与代码一致、这个仓库里 graft 已经省了多少 token。徽章的卡片上有一个 **Build** 按钮——重建索引,或者创建第一个索引。
|
|
19
|
+
- **给模型五个工具** — `graft_ask`、`graft_grep`、`graft_callers`、`graft_skeleton`、`graft_map`——按会话解析,所以一个 dsh 可以同时服务多个工作区,git worktree 也不例外,每个都有自己的图。
|
|
20
|
+
- **`/graft`** 构建或重建索引,模型改完文件后**自动重建**。
|
|
21
|
+
- **`graft viz` 按钮**:在 dsh 内置的右侧边栏(0.1.5+)打开图;如果你还在用 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar),就在那里打开;两者都没有时退到浏览器标签页。
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
dsh plugin --profile web add dsh-graft-plugin
|
|
27
|
+
dsh --profile web
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**pnpm 10 及以后会默认拦截未批准包的 `postinstall` 脚本**,而只要安装以非零退出,dsh 就会跳过写入插件的 bundle 行——依赖装上了,插件却隐形,dsh 还启动得干干净净,没有任何可搜索的报错。如果 `add` 以 `ERR_PNPM_IGNORED_BUILDS` 结尾,先批准再重跑:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
cd ~/.dsh/profiles/web && pnpm approve-builds # 勾选 dsh-graft-plugin
|
|
34
|
+
dsh plugin --profile web add dsh-graft-plugin # 重跑,让 bundle 行写入
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
确认它挂载了——插件必须同时出现在 profile 的 `package.json` 的 `dependencies` 和 `dsh.profile.bundles` 里:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
cd ~/.dsh/profiles/web && node -e "const p=require('./package.json');
|
|
41
|
+
console.log(p.dependencies['dsh-graft-plugin'],
|
|
42
|
+
p.dsh.profile.bundles.includes('dsh-graft-plugin'))"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
这里的每个工具都要调用 `graft` CLI,所以 PATH 上必须有 `@nanonets/graft`:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
npm install -g @nanonets/graft
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`postinstall` 会在**你的包管理器愿意运行生命周期脚本时**替你装好——pnpm 10+ 默认拦截它们,所以在 pnpm 下请把上面这条命令当作必需步骤,而不是后备。若全局 npm 前缀需要提权,postinstall 会说明并打印那条需要手动执行的命令。
|
|
52
|
+
|
|
53
|
+
然后给仓库建一次索引:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
cd <your repo>
|
|
57
|
+
graft build
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 桌面应用
|
|
61
|
+
|
|
62
|
+
桌面版 dsh 从自己的 **Plugins** 设置页安装插件——不用 CLI,不用 profile 目录:
|
|
63
|
+
|
|
64
|
+
1. 打开 **Plugins**(设置页左侧栏),点 **Add plugin**。
|
|
65
|
+
2. 把 GitHub 仓库地址粘进输入框(包名 `dsh-graft-plugin` 也可以):
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
https://github.com/adithyanraj03/dsh-graft-plugin
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
3. 点 **Install**。
|
|
72
|
+
|
|
73
|
+

|
|
74
|
+
|
|
75
|
+
对话框会切换到 **Installed** 确认页,插件同时出现在设置页底部的 **Installed** 列表里:
|
|
76
|
+
|
|
77
|
+

|
|
78
|
+
|
|
79
|
+
> 对话框也提示:已安装的插件**目前不会自动更新**——升级请先卸载再重装。graft CLI 的要求(`npm install -g @nanonets/graft`)不变。
|
|
80
|
+
|
|
81
|
+
### 侧边栏标签页
|
|
82
|
+
|
|
83
|
+
在 dsh `0.1.5` 及以后,这个按钮会在 **dsh 自己的右侧边栏**里打开图——一个名为 Graft 的标签页,同时列在边栏引导页里,说明是 "The graft graph for this workspace"——再次点击会聚焦已打开的标签页。这条路径不需要安装任何东西:注册是软性的,所以没有右侧边栏的旧版 dsh 会退到已挂载的 `dsh-better-sidebar`,两者都没有时退到浏览器标签页。
|
|
84
|
+
|
|
85
|
+
如果你的 profile 还在用 `dsh-better-sidebar`,会**优先**尝试那条路径,行为和以前完全一样。从 0.3.0 起它是**可选对等依赖(optional peer dependency)**——dsh 不再替你下载,想要就自己加(在 dsh `0.1.5-rc.2` 及以后它本来就挂不起来,多数 profile 可以跳过):
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
dsh plugin --profile web add dsh-better-sidebar
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
> **兼容性。** `dsh-better-sidebar` 0.18.x 需要 `@deepseek-ai/dsh-client-ui-primitives`,而 dsh 在 `0.1.5-rc.2` 移除了它。在该版本及以后它挂不起来——那些 profile 正好由内置右侧边栏接管。本插件其余部分——徽章、工具、`/graft`、自动重建——都不受影响。
|
|
92
|
+
|
|
93
|
+
徽章、工具、`/graft` 和自动重建在完全没有侧边栏时也都工作;按钮只是在两个都没有时退到浏览器标签页。
|
|
94
|
+
|
|
95
|
+
> 这个插件**故意不**自己插入 `dsh-better-sidebar` 行。那个包自己的 bundle 行带一个守卫:当已有另一个启用的行挂载同一个包时,它会自我禁用。第二条不同 id 的行会让这个守卫变成循环判断,输掉的那一边是*你现有的边栏悄悄自我禁用*。一条显式命令比这个风险值钱。
|
|
96
|
+
|
|
97
|
+
## 你会得到什么
|
|
98
|
+
|
|
99
|
+
### 徽章
|
|
100
|
+
|
|
101
|
+
待在输入框里模型名的旁边:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
● graft · my-repo in sync
|
|
105
|
+
◐ graft · my-repo syncing
|
|
106
|
+
▲ graft · my-repo stale
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
悬停(或点击)打开一张卡片:解析出的根目录、节点与边数、新鲜度、累计省下的 token,以及 `graft viz` 按钮。
|
|
110
|
+
|
|
111
|
+

|
|
112
|
+
|
|
113
|
+
卡片头部在状态胶囊旁边有一个 **Build** 按钮。在已有索引的仓库里,它跑的就是自动重建用的那套同步——graft 自己的 sync——并停在 "Building…" 直到胶囊显示 *in sync*,两分钟后放弃并给出原因。在还没有索引的工作区里,Build 会先用 dsh 自己的对话框确认("Build graft index?" — Cancel / Build index;取消、Escape 或点框外都不会构建),然后跑一次纯离线的 `graft build`,在那里写出一个 `graft/` 目录。
|
|
114
|
+
|
|
115
|
+
`graft_*` 工具运行期间,徽章的圆点会闪紫色。
|
|
116
|
+
|
|
117
|
+
徽章、卡片和可视化标签页全部用 dsh 自己的 `--dsw-*` 主题变量绘制,因此跟随当前主题——包括主题插件。
|
|
118
|
+
|
|
119
|
+
链接的 git worktree 拥有自己的图,绝不借用主检出(main checkout)的:卡片和边栏标签条都会标出它所属的主检出(`git worktree of <repo>`)。还没有图时,在 worktree 里 `/graft` 会从主检出播种出第一张图。
|
|
120
|
+
|
|
121
|
+
根目录是从**会话自己的工作区**解析的,不是从 dsh 的启动位置。这正是本插件存在、而不是用 `graft mcp` 服务器的原因:`graft mcp` 在启动时从自己的工作目录解析一次仓库,之后没有任何办法改指。从主目录启动时,它对你打开的每个工作区都回答*"no graph found"*。
|
|
122
|
+
|
|
123
|
+
### 可视化
|
|
124
|
+
|
|
125
|
+
`graft viz` 按钮把图作为一个标签页打开——在 `0.1.5`+ 的 dsh 内置右侧边栏里,或者在你仍在使用的 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 里。上下文视图铺开整张图:
|
|
126
|
+
|
|
127
|
+

|
|
128
|
+
|
|
129
|
+
代码视图下钻到单个文件——它包含什么、依赖什么、被谁依赖:
|
|
130
|
+
|
|
131
|
+

|
|
132
|
+
|
|
133
|
+
### 工具
|
|
134
|
+
|
|
135
|
+
| 工具 | 回答什么 |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `graft_ask` | "X 是怎么工作的" / "Y 在哪"——带排序的命中,代码直接内联在精确的 `file:line` |
|
|
138
|
+
| `graft_grep` | 每一处出现,按所在符号分组(`graft_ask` 只给 top-N,会漏) |
|
|
139
|
+
| `graft_callers` | 谁调用一个符号、它调用谁,或改名前的完整爆炸半径 |
|
|
140
|
+
| `graft_skeleton` | 一个文件的完整 API,约 200 token |
|
|
141
|
+
| `graft_map` | 在陌生目录树里定位方向 |
|
|
142
|
+
|
|
143
|
+
它们都不接受布尔参数,而是用字符串枚举——`detail: "full"` 而不是 `full: true`——对模型更好读,也绕开了一些 OpenAI 兼容服务器上的一个真实故障:*设置*了布尔值的工具调用会被发成字面的 `<tool_call>` 文本,永远不执行。
|
|
144
|
+
|
|
145
|
+
### `/graft`
|
|
146
|
+
|
|
147
|
+
- `/graft` — 构建索引,已有则重建
|
|
148
|
+
- `/graft status` — 把徽章知道的东西打成文字
|
|
149
|
+
- `/graft deep` — 完整重建
|
|
150
|
+
|
|
151
|
+
### 自动重建
|
|
152
|
+
|
|
153
|
+
模型写入或编辑文件后,索引在后台重建,并做了防抖,长回合不会每次击键都重建。这里复用 graft 自己的 sync runner,而不是重新实现一遍,所以它不会和 `graft build` 的行为漂移。
|
|
154
|
+
|
|
155
|
+
## 配置
|
|
156
|
+
|
|
157
|
+
全部可选,全部写在 profile 的 `cordis.patch.yml` 里本插件的那一行上:
|
|
158
|
+
|
|
159
|
+
```yaml
|
|
160
|
+
- id: graft-status
|
|
161
|
+
name: 'dsh-graft-plugin'
|
|
162
|
+
config:
|
|
163
|
+
cwd: 'C:/path/to/repo' # 固定到一个仓库,而不是按会话解析
|
|
164
|
+
tools: false # 去掉 graft_* 工具,保留徽章
|
|
165
|
+
command: false # 去掉 /graft
|
|
166
|
+
promptSection: false # 不再告诉模型使用 graft
|
|
167
|
+
autoBuild: false # 不再在编辑后重建(卡片上的 Build 按钮仍然可用)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 系统要求
|
|
171
|
+
|
|
172
|
+
| dsh | 状态 |
|
|
173
|
+
|---|---|
|
|
174
|
+
| `0.2.1-rc.2` | 测试套件针对 `0.2.1-rc.2` 的包全部通过——徽章、工具、`/graft`、自动重建和面向模型的指引;双形态 codec 在 0.1 和 0.2 宿主上都能加载 |
|
|
175
|
+
| `0.1.7-rc.2` | 在真实 profile 上测试过(0.3.0)——徽章、工具、`/graft`、自动重建和面向模型的指引全部验证 |
|
|
176
|
+
| `0.1.2-rc.1` – `0.1.0-rc.7` | 测试过,完整功能——`graft viz` 标签页经由 `dsh-better-sidebar` |
|
|
177
|
+
| `0.1.5-rc.2` / `0.1.5` | 测试过——徽章、工具、`/graft`、自动重建全部工作;在 `0.1.5` 上 `graft viz` 按钮在内置右侧边栏打开图 |
|
|
178
|
+
| `0.2.0-rc.2` | 需要插件 `0.2.1`+——更早的发行版无法激活(见故障排查) |
|
|
179
|
+
|
|
180
|
+
- Node 22+
|
|
181
|
+
- PATH 上的 `graft` CLI(`npm install -g @nanonets/graft`)。bun 的全局安装(`bun add -g @nanonets/graft`)也能被识别,经由 `$BUN_INSTALL` 或 `~/.bun`。
|
|
182
|
+
|
|
183
|
+
客户端 bundle 只依赖 `react`——这就是它能在 dsh `0.1.5-rc.2` 移除一批客户端包、弄坏了好几个相邻插件的情况下存活的原因。
|
|
184
|
+
|
|
185
|
+
## 开发
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
npm install
|
|
189
|
+
npm test # 可移植:在临时目录里构建一个合成的 graft 索引
|
|
190
|
+
npm run test:live # 用真实 graft CLI 对着真实仓库跑
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`npm test` 不需要任何 graft 索引,机器上也不需要装 graft。唯一会真建索引的那个套件在 graft 缺失时会大声地自我跳过——缺 CLI 是一种环境状态,不是缺陷。
|
|
194
|
+
|
|
195
|
+
### 两个标识符,故意不同
|
|
196
|
+
|
|
197
|
+
cordis 行的 `id`(`graft-status`)是本插件自己的把手——它键控存储文件、prompt 区块和每个 effect 标签,并且在改名中保持稳定。
|
|
198
|
+
|
|
199
|
+
客户端 bundle 的 `__ModuleLoader__.load({ id })` **不是**那个把手。它必须是已发布的包名:dsh 用 `entry.options.name`——即 `cordis.patch.yml` 里的 `name:`——构建每条客户端行,把 bundle 服务在 `/plugins/<name>/client.js`,然后断言有一个以同一名字注册的工厂。在那里用行 id 会让每次启动都失败:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
bundle /plugins/dsh-graft-plugin/client.js loaded without
|
|
203
|
+
registering "dsh-graft-plugin" via __ModuleLoader__.load
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
`npm test` 双向守着这一点(这个守卫随 0.1.1 的修复加入)。
|
|
207
|
+
|
|
208
|
+
## 故障排查
|
|
209
|
+
|
|
210
|
+
**徽章没出现,而 dsh 启动毫无报错。** 插件在 profile 的 `package.json` 的 `dependencies` 里,却不在 `dsh.profile.bundles` 里——pnpm 10+ 下 `add` 以 `ERR_PNPM_IGNORED_BUILDS` 非零退出时就是这样:dsh 跳过 bundle 行,启动看起来一切正常。修法:在 profile 目录里 `pnpm approve-builds`(勾选 `dsh-graft-plugin`),然后重跑 `dsh plugin --profile web add dsh-graft-plugin`。如果 `pnpm approve-builds` 说没有待批准的包,去 profile 的 `pnpm-workspace.yaml` 里找未回答的 `dsh-graft-plugin` 条目(pnpm 的批准占位符),先把它的值改成 `true`。
|
|
211
|
+
|
|
212
|
+
**在 dsh 0.2 上插件加载失败,报 `strict codec has no create() factory`,dsh 还提议移除它。** dsh 0.2 要求每个 strict remote codec 都带一个 `create()` schema 工厂;`0.2.1` 之前的插件发行版只有 0.1 的 `schema` 键。升级到 `0.2.1` 或更新版本——它两种都带,0.1 和 0.2 上都能加载。
|
|
213
|
+
|
|
214
|
+
**`/graft` 说 graft CLI 不在 PATH 上。** postinstall 被拦截或被跳过了(见安装):`npm install -g @nanonets/graft`。
|
|
215
|
+
|
|
216
|
+
## 许可证
|
|
217
|
+
|
|
218
|
+
MIT
|
package/assets/icon.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-graft-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Shows which graft index a dsh session is serving and whether it still matches the code, and gives the model graft_ask, graft_grep, graft_callers, graft_skeleton and graft_map as native tools.",
|
|
5
|
+
"icon": "assets/icon.png",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "src/index.js",
|
|
7
8
|
"exports": {
|
|
@@ -28,7 +29,8 @@
|
|
|
28
29
|
"scripts/test-guidance.mjs",
|
|
29
30
|
"README.md",
|
|
30
31
|
"LICENSE",
|
|
31
|
-
"screenshots.json"
|
|
32
|
+
"screenshots.json",
|
|
33
|
+
"assets/icon.png"
|
|
32
34
|
],
|
|
33
35
|
"scripts": {
|
|
34
36
|
"test": "node scripts/test-harness.mjs && node scripts/test-autosync.mjs && node scripts/test-command.mjs && node scripts/test-guidance.mjs",
|
package/src/client.js
CHANGED
|
@@ -182,7 +182,7 @@ window.__ModuleLoader__.load({
|
|
|
182
182
|
".gs-chip.gs-clickable:focus-visible{outline:2px solid var(--dsw-focus-ring-color,var(--dsw-alias-brand-primary,#4b8bd6));outline-offset:2px}",
|
|
183
183
|
".gs-viz{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;",
|
|
184
184
|
"padding:0;border:0;border-radius:var(--dsw-radius-sm,8px);background:transparent;color:var(--dsw-alias-label-secondary,inherit);",
|
|
185
|
-
"cursor:pointer;--accent:var(--
|
|
185
|
+
"cursor:pointer;--accent:var(--dsh-graft-accent,#e5484d)}",
|
|
186
186
|
".gs-viz:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(128,128,128,.14))}",
|
|
187
187
|
".gs-viz:disabled{opacity:.5;cursor:progress}",
|
|
188
188
|
".gs-viz.gs-err{color:var(--dsw-alias-state-error-primary,#e5484d)}",
|
|
@@ -512,21 +512,28 @@ window.__ModuleLoader__.load({
|
|
|
512
512
|
);
|
|
513
513
|
}
|
|
514
514
|
|
|
515
|
-
/** The
|
|
515
|
+
/** The graft mark: thick trunk with a leaf, thin branches, accent node.
|
|
516
|
+
* The same design as `assets/icon.svg` and the banners, at button scale
|
|
517
|
+
* (trunk and branch widths match the tuned vector's tube widths).
|
|
518
|
+
* `--accent` is set by `.gs-viz` to the graft red — deliberately NOT the
|
|
519
|
+
* theme's brand-primary, which some themes set to white and which then
|
|
520
|
+
* washes the accent out of the mark entirely; themes may opt in with
|
|
521
|
+
* `--dsh-graft-accent`. */
|
|
516
522
|
function GraphIcon() {
|
|
517
523
|
return h(
|
|
518
524
|
"svg",
|
|
519
525
|
{ width: 19, height: 19, viewBox: "0 0 24 24", "aria-hidden": "true" },
|
|
526
|
+
h("path", { d: "M11.6 17.8 C9.9 17.9 8.2 17.1 7.3 15.4 C9.2 14.9 11 15.9 11.6 17.8 Z", fill: "var(--accent)" }),
|
|
520
527
|
h(
|
|
521
528
|
"g",
|
|
522
|
-
{ fill: "none", stroke: "currentColor",
|
|
523
|
-
h("path", { d: "M12 21 V12" }),
|
|
524
|
-
h("path", { d: "M12 12 L6.8 6.6" }),
|
|
525
|
-
h("path", { stroke: "var(--accent)", d: "M12 12 L17.4 7.6" }),
|
|
529
|
+
{ fill: "none", stroke: "currentColor", strokeLinecap: "round" },
|
|
530
|
+
h("path", { strokeWidth: 3.1, d: "M12 21 V12" }),
|
|
531
|
+
h("path", { strokeWidth: 1.7, d: "M12 12 L6.8 6.6" }),
|
|
532
|
+
h("path", { stroke: "var(--accent)", strokeWidth: 1.8, d: "M12 12 L17.4 7.6" }),
|
|
526
533
|
),
|
|
527
|
-
h("circle", { cx: 12, cy: 12, r: 2.
|
|
528
|
-
h("circle", { cx: 6.8, cy: 6.6, r: 1.
|
|
529
|
-
h("circle", { cx: 17.4, cy: 7.6, r: 1.
|
|
534
|
+
h("circle", { cx: 12, cy: 12, r: 2.2, fill: "currentColor" }),
|
|
535
|
+
h("circle", { cx: 6.8, cy: 6.6, r: 1.8, fill: "currentColor" }),
|
|
536
|
+
h("circle", { cx: 17.4, cy: 7.6, r: 1.8, fill: "var(--accent)" }),
|
|
530
537
|
);
|
|
531
538
|
}
|
|
532
539
|
|