dsh-graft-plugin 0.1.0 → 0.1.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 +49 -5
- package/package.json +1 -2
- package/scripts/test-harness.mjs +14 -0
- package/src/client.js +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-graft-plugin
|
|
2
2
|
|
|
3
|
-
            
|
|
4
4
|
|
|
5
5
|
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
6
|
|
|
@@ -18,12 +18,29 @@ dsh plugin --profile web add dsh-graft-plugin
|
|
|
18
18
|
dsh --profile web
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
**pnpm 10 and later block `postinstall` scripts from unapproved packages**, and dsh skips writing the plugin's bundle row whenever the install exits non-zero — the dependency lands, the plugin stays invisible, and dsh starts up cleanly with no error to search for. If `add` ends with `ERR_PNPM_IGNORED_BUILDS`, approve and re-run it:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
cd ~/.dsh/profiles/web && pnpm approve-builds # tick dsh-graft-plugin
|
|
25
|
+
dsh plugin --profile web add dsh-graft-plugin # re-run so the bundle row gets written
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Confirm it mounted — the plugin must appear in **both** `dependencies` and `dsh.profile.bundles` in the profile's `package.json`:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
cd ~/.dsh/profiles/web && node -e "const p=require('./package.json');
|
|
32
|
+
console.log(p.dependencies['dsh-graft-plugin'],
|
|
33
|
+
p.dsh.profile.bundles.includes('dsh-graft-plugin'))"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Every tool here shells out to the `graft` CLI, so it needs `@nanonets/graft` on PATH:
|
|
22
37
|
|
|
23
38
|
```sh
|
|
24
39
|
npm install -g @nanonets/graft
|
|
25
40
|
```
|
|
26
41
|
|
|
42
|
+
A `postinstall` does this for you **when your package manager runs lifecycle scripts** — under pnpm 10+ they are blocked by default, so treat the command above as the required step there, not a fallback. If your global npm prefix needs elevation, the postinstall says so and prints the one command to run by hand.
|
|
43
|
+
|
|
27
44
|
Then index a repo once:
|
|
28
45
|
|
|
29
46
|
```sh
|
|
@@ -33,12 +50,14 @@ graft build
|
|
|
33
50
|
|
|
34
51
|
### The sidebar tab
|
|
35
52
|
|
|
36
|
-
The `graft viz` button needs `dsh-better-sidebar` **mounted**. It ships as a dependency of this plugin, so it is already downloaded — but dsh only mounts what the profile lists:
|
|
53
|
+
The `graft viz` button needs `dsh-better-sidebar` **mounted**. It ships as a dependency of this plugin (0.18.x), so it is already downloaded — but dsh only mounts what the profile lists:
|
|
37
54
|
|
|
38
55
|
```sh
|
|
39
56
|
dsh plugin --profile web add dsh-better-sidebar
|
|
40
57
|
```
|
|
41
58
|
|
|
59
|
+
> **Compatibility.** `dsh-better-sidebar` 0.18.x requires `@deepseek-ai/dsh-client-ui-primitives`, which dsh removed in `0.1.5-rc.2`. On that version or later the tab will not mount and the button reports the sidebar as unavailable. Everything else in this plugin — chip, tools, `/graft`, auto-rebuild — is unaffected.
|
|
60
|
+
|
|
42
61
|
Skip it if you do not want the tab. The chip, the tools, `/graft` and the auto-rebuild all work without it; the button just reports that the sidebar is unavailable.
|
|
43
62
|
|
|
44
63
|
> This plugin does **not** insert a `dsh-better-sidebar` row itself, on purpose. That package's own bundle row carries a guard that disables it when another enabled row already mounts the same package. A second row with a different id makes that guard circular, and the losing outcome is *your existing sidebar silently disabling itself*. One explicit command is worth more than that risk.
|
|
@@ -110,9 +129,15 @@ All optional, all on the plugin's row in your profile's `cordis.patch.yml`:
|
|
|
110
129
|
|
|
111
130
|
## Requirements
|
|
112
131
|
|
|
113
|
-
|
|
132
|
+
| dsh | status |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `0.1.2-rc.1` – `0.1.0-rc.7` | tested, full feature set |
|
|
135
|
+
| `0.1.5-rc.2` | tested — chip, tools, `/graft` and auto-rebuild all work; the `graft viz` tab does not mount (see the sidebar note above) |
|
|
136
|
+
|
|
114
137
|
- Node 22+
|
|
115
|
-
- the `graft` CLI on PATH (
|
|
138
|
+
- the `graft` CLI on PATH (`npm install -g @nanonets/graft`)
|
|
139
|
+
|
|
140
|
+
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.
|
|
116
141
|
|
|
117
142
|
## Development
|
|
118
143
|
|
|
@@ -124,6 +149,25 @@ npm run test:live # drives the real graft CLI against a real repo
|
|
|
124
149
|
|
|
125
150
|
`npm test` needs no graft index and no graft install anywhere on the machine. The one suite that does build a real index skips itself, loudly, when graft is absent — a missing CLI is a setup state, not a defect.
|
|
126
151
|
|
|
152
|
+
### Two identifiers, deliberately different
|
|
153
|
+
|
|
154
|
+
The cordis row `id` (`graft-status`) is this plugin's own handle — it keys the storage file, the prompt section and every effect label, and is stable across renames.
|
|
155
|
+
|
|
156
|
+
The client bundle's `__ModuleLoader__.load({ id })` is **not** that handle. It must be the published package name: dsh builds each client row from `entry.options.name` — the `name:` in `cordis.patch.yml` — serves the bundle at `/plugins/<name>/client.js`, then asserts that a factory registered under that same name. Using the row id there fails every boot with:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
bundle /plugins/dsh-graft-plugin/client.js loaded without
|
|
160
|
+
registering "dsh-graft-plugin" via __ModuleLoader__.load
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`npm test` guards this both ways (the guard was added with the 0.1.1 fix).
|
|
164
|
+
|
|
165
|
+
## Troubleshooting
|
|
166
|
+
|
|
167
|
+
**No chip appears and dsh started without errors.** The plugin is in the profile's `package.json` `dependencies` but not in `dsh.profile.bundles` — which happens under pnpm 10+ when the `add` ends non-zero on `ERR_PNPM_IGNORED_BUILDS`; dsh skips the bundle row in that case and starts up looking healthy. Fix: `pnpm approve-builds` in the profile directory (tick `dsh-graft-plugin`), then re-run `dsh plugin --profile web add dsh-graft-plugin`. If `pnpm approve-builds` reports nothing awaiting approval, check `pnpm-workspace.yaml` for an unanswered `dsh-graft-plugin` entry (pnpm's approval placeholder) and set its value to `true` first.
|
|
168
|
+
|
|
169
|
+
**`/graft` says the graft CLI is not on PATH.** The postinstall was blocked or skipped (see Install): `npm install -g @nanonets/graft`.
|
|
170
|
+
|
|
127
171
|
## Licence
|
|
128
172
|
|
|
129
173
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-graft-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.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
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
"client": {
|
|
42
42
|
"platform": "web",
|
|
43
43
|
"inject": [
|
|
44
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
45
44
|
"@deepseek-ai/dsh-api-remotes"
|
|
46
45
|
]
|
|
47
46
|
}
|
package/scripts/test-harness.mjs
CHANGED
|
@@ -215,6 +215,20 @@ check('the tab is opened exactly once', opens.length === 1, opens.join(' | '))
|
|
|
215
215
|
check('and never with noopener', opens.every((call) => !call.includes('noopener')), opens.join(' | '))
|
|
216
216
|
check('and opened blank, to be navigated later', (opens[0] ?? '').includes('"", "_blank"'), opens[0])
|
|
217
217
|
|
|
218
|
+
console.log('\n--- the client module key ---')
|
|
219
|
+
// The client loader keys bundles by the package name — entry.options.name in
|
|
220
|
+
// cordis.patch.yml — and arrive() asserts factories.has(that name). The row id
|
|
221
|
+
// `graft-status` is a DIFFERENT namespace (storage keys, prompt section,
|
|
222
|
+
// effect labels) and must stay put there. When the two were conflated, the
|
|
223
|
+
// factory landed under the row id and the assert fired on every boot with the
|
|
224
|
+
// chip and tab missing. That shipped as 0.1.0; this guard is the reason it
|
|
225
|
+
// will not ship again.
|
|
226
|
+
check(
|
|
227
|
+
'registers under the package name, not the row id',
|
|
228
|
+
/__ModuleLoader__\.load\(\{\s*\r?\n\s*id:\s*"dsh-graft-plugin"/.test(clientSource),
|
|
229
|
+
)
|
|
230
|
+
check('and never under the row id', !/__ModuleLoader__\.load\(\{\s*\r?\n\s*id:\s*"graft-status"/.test(clientSource))
|
|
231
|
+
|
|
218
232
|
console.log('\n--- the sidebar tab is a consumer, not a patch ---')
|
|
219
233
|
// dsh-better-sidebar is never edited by this plugin: the tab is contributed
|
|
220
234
|
// through its documented `ctx.betterSidebar` service, which its README states
|
package/src/client.js
CHANGED