dsh-custom-mode 1.0.0 → 1.0.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 +33 -31
- package/client.js +6 -6
- package/composition.mjs +30 -8
- package/index.mjs +17 -4
- package/locales.mjs +6 -6
- package/package.json +14 -5
package/README.md
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
1
|
# dsh-custom-mode
|
|
2
2
|
|
|
3
|
-
The **settings-page half** of [dsh-custom-mode](https://github.com/BOWLUNA/dsh-custom-mode)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
new
|
|
3
|
+
The **settings-page half** of [dsh-custom-mode](https://github.com/BOWLUNA/dsh-custom-mode) — a Web UI for
|
|
4
|
+
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (dsh) agent modes: choose a mode's base
|
|
5
|
+
composition, toggle the plugin rows it mounts, and edit its **system prompt**, which is a plain file the
|
|
6
|
+
agent loop re-reads before every model step — **a save applies on the next step, with no restart and no new
|
|
7
|
+
session**. Several modes ("assistants") live side by side, each with its own prompt.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
Searched for as: custom mode · custom prompt · system-prompt editor · multi-mode / several assistants ·
|
|
10
|
+
自定义模式 · 自定义提示词 · 多助手/多模式.
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+

|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
settings section (base-mode picker, per-row plugin switches, prompt editor, mode rename).
|
|
14
|
+

|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
(`preset/agent.cordis.yml`, `prompt-reader.mjs`, `prompt-tool.mjs`, `prompt.md`) that dsh discovers
|
|
17
|
-
under `$DSH_HOME/.agent-presets/<id>/`. It comes from the GitHub repository.
|
|
16
|
+

|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
## Install
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
```sh
|
|
21
|
+
dsh plugin --profile web add dsh-custom-mode
|
|
22
|
+
```
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
**That one command is the whole install.** The package carries the agent preset, and the host half writes it
|
|
25
|
+
into `$DSH_HOME/.agent-presets/` on first activation — filling in only what is missing, so a `prompt.md` you
|
|
26
|
+
wrote yourself is never overwritten.
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
To keep the source around as well, clone the repository and run `./install.sh` instead; it does the same two
|
|
29
|
+
things explicitly, and `./uninstall.sh` undoes them (keeping your prompt unless you pass `--purge`).
|
|
30
|
+
|
|
31
|
+
The mode is **web-profile only**: `agent-presets`, the service that mounts presets at all, ships with dsh's
|
|
32
|
+
`web` profile. In `tui` / `headless` this package activates but registers nothing.
|
|
31
33
|
|
|
32
34
|
## Requirements
|
|
33
35
|
|
|
34
|
-
-
|
|
35
|
-
it only reads the host services dsh injects
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
- **dsh `>=0.1.6-alpha.1`** — declared in `engines.dsh` and as an *optional* peer range. This package never
|
|
37
|
+
imports `@deepseek-ai/dsh`; it only reads the host services dsh injects.
|
|
38
|
+
- **No build step, no dependencies**: the source is published as-is and uses only Node's standard library.
|
|
39
|
+
- The package version is its own line (`1.0.0`, `1.0.1`, …). Which dsh it supports is declared in
|
|
40
|
+
`engines.dsh`; see the repository README's "Versioning" section.
|
|
39
41
|
|
|
40
42
|
## Documentation
|
|
41
43
|
|
|
@@ -45,18 +47,18 @@ The full documentation is bilingual in the repository:
|
|
|
45
47
|
[中文说明](https://github.com/BOWLUNA/dsh-custom-mode/blob/main/README.zh.md)
|
|
46
48
|
- [Troubleshooting](https://github.com/BOWLUNA/dsh-custom-mode/blob/main/docs/TROUBLESHOOTING.md) —
|
|
47
49
|
every failure that was actually reproduced, with symptoms, cause and a way out
|
|
48
|
-
- [
|
|
49
|
-
|
|
50
|
-
- [Architecture](https://github.com/BOWLUNA/dsh-custom-mode/blob/main/docs/ARCHITECTURE.md) — why
|
|
51
|
-
|
|
50
|
+
- [Measurements](https://github.com/BOWLUNA/dsh-custom-mode/blob/main/docs/MEASUREMENTS.md) — the commands
|
|
51
|
+
and raw output behind every claim
|
|
52
|
+
- [Architecture](https://github.com/BOWLUNA/dsh-custom-mode/blob/main/docs/ARCHITECTURE.md) — why this had
|
|
53
|
+
to be two artifacts, and which host APIs it depends on
|
|
52
54
|
|
|
53
55
|
## Security note
|
|
54
56
|
|
|
55
57
|
The route this package serves runs the platform's own browser-trust check
|
|
56
58
|
(`ctx.connection.requestRejection`) before anything else and **fails closed** when that service is
|
|
57
59
|
unavailable. Before that check existed, the route could be read and written unauthenticated — see
|
|
58
|
-
[SECURITY.md](https://github.com/BOWLUNA/dsh-custom-mode/blob/main/SECURITY.md) for the affected
|
|
59
|
-
|
|
60
|
+
[SECURITY.md](https://github.com/BOWLUNA/dsh-custom-mode/blob/main/SECURITY.md) for the affected range and
|
|
61
|
+
the mitigation.
|
|
60
62
|
|
|
61
63
|
## License
|
|
62
64
|
|
package/client.js
CHANGED
|
@@ -103,11 +103,11 @@ try {
|
|
|
103
103
|
"name.placeholder": "自定义模式",
|
|
104
104
|
"name.descriptionPlaceholder": "模式描述(显示在模式选择器里,可留空)",
|
|
105
105
|
"mode.heading": "基础模式",
|
|
106
|
-
"mode.hint": "
|
|
106
|
+
"mode.hint": "选一个官方模式作为底子,下面再按行微调。注意:底子只决定**行集合**与工具能力 —— 本模式的 persona 行始终替换掉底子那一行(提示词由你编辑,complete: false),底子的提示词语义不会被继承。改完保存后,新建会话即生效,不需要重启。",
|
|
107
107
|
"rows.heading": "插件开关",
|
|
108
108
|
"rows.hint": "逐行控制这个模式挂载哪些插件,和官方插件列表一样按行铺开。没拨过的行保持官方默认(含平台判断);你手动拨了就以你的为准。",
|
|
109
109
|
"prompt.heading": "系统提示词",
|
|
110
|
-
"prompt.hint": "
|
|
110
|
+
"prompt.hint": "这段文本在每个模型调用前重新读取,所以保存后下一步即生效,且只影响使用这个助手的会话。「导入」把文件读进编辑器(未保存前不写入任何东西);「导出」把当前文本存成 .md 文件。",
|
|
111
111
|
"status.enabled": "已启用",
|
|
112
112
|
"status.disabled": "已停用",
|
|
113
113
|
"status.changed": "已改",
|
|
@@ -181,7 +181,7 @@ try {
|
|
|
181
181
|
"base.ptc.label": "PTC 模式",
|
|
182
182
|
"base.ptc.note": "在标准模式基础上启用 PTC 工具呈现(tool-presentation)",
|
|
183
183
|
"base.minimal.label": "极简模式",
|
|
184
|
-
"base.minimal.note": "只有 Shell 与终端,共 7
|
|
184
|
+
"base.minimal.note": "只有 Shell 与终端,共 7 行;没有文件、检索、技能、子代理。系统提示词不是极简那一套(persona 行被本模式替换)",
|
|
185
185
|
"base.cordis.label": "Cordis 模式",
|
|
186
186
|
"base.cordis.note": "标准模式 + 读写运行时的 Cordis 工具集,可让 agent 自己改 harness"
|
|
187
187
|
}
|
|
@@ -233,11 +233,11 @@ try {
|
|
|
233
233
|
"name.placeholder": "Custom mode",
|
|
234
234
|
"name.descriptionPlaceholder": "Mode description (shown in the mode picker, optional)",
|
|
235
235
|
"mode.heading": "Base mode",
|
|
236
|
-
"mode.hint": "
|
|
236
|
+
"mode.hint": "Pick an official mode as the base, then adjust it row by row. Note: the base only decides which rows exist — this mode always replaces the base's persona row with its own reader (complete: false), so the base's prompt semantics are not inherited. A save applies to the next new session; no restart needed.",
|
|
237
237
|
"rows.heading": "Plugin switches",
|
|
238
238
|
"rows.hint": "Control row by row which plugins this mode mounts, laid out like the official plugin list. Untouched rows keep the official default (platform conditions included); your manual choice wins.",
|
|
239
239
|
"prompt.heading": "System prompt",
|
|
240
|
-
"prompt.hint": "This text is re-read before every model call, so a save applies on the next step
|
|
240
|
+
"prompt.hint": "This text is re-read before every model call, so a save applies on the next step and only affects sessions on this assistant. \"Import\" reads a file into the editor (nothing is written until you save); \"Export\" saves the current text as a .md file.",
|
|
241
241
|
"status.enabled": "Enabled",
|
|
242
242
|
"status.disabled": "Disabled",
|
|
243
243
|
"status.changed": "changed",
|
|
@@ -311,7 +311,7 @@ try {
|
|
|
311
311
|
"base.ptc.label": "PTC",
|
|
312
312
|
"base.ptc.note": "Standard plus PTC tool presentation (tool-presentation)",
|
|
313
313
|
"base.minimal.label": "Minimal",
|
|
314
|
-
"base.minimal.note": "Shell and terminal only, 7 rows; no files, search, skills or subagents",
|
|
314
|
+
"base.minimal.note": "Shell and terminal only, 7 rows; no files, search, skills or subagents. The system prompt is not minimal's either (this mode replaces the persona row)",
|
|
315
315
|
"base.cordis.label": "Cordis",
|
|
316
316
|
"base.cordis.note": "Standard plus the Cordis toolset, letting the agent modify its own harness"
|
|
317
317
|
}
|
package/composition.mjs
CHANGED
|
@@ -297,10 +297,16 @@ function setDisabled(segmentText, disabled) {
|
|
|
297
297
|
const own = disabledLineAt(indent)
|
|
298
298
|
const index = lines.findIndex((line) => own.test(line))
|
|
299
299
|
if (index !== -1) {
|
|
300
|
+
const shipped = lines[index].trim().replace(/^disabled:\s*/, '')
|
|
300
301
|
if (disabled) {
|
|
301
302
|
lines[index] = `${' '.repeat(indent)}disabled: true`
|
|
303
|
+
} else if (shipped.startsWith('!!js') && evalDisabledExpression(shipped) !== true) {
|
|
304
|
+
// 显式打开,但出厂那行是平台表达式、且它在本机求值就是"开":这不是覆盖,而是**撤销覆盖** ——
|
|
305
|
+
// 保持出厂表达式原样,这一行就回到"跟随平台"。(原先这里删掉整行,结果是文件既不是出厂原样、
|
|
306
|
+
// 也不是显式覆盖,页面却显示"未拨过" —— 文件与显示同时失真。)
|
|
307
|
+
return segmentText
|
|
302
308
|
} else {
|
|
303
|
-
lines.
|
|
309
|
+
lines[index] = `${' '.repeat(indent)}disabled: false`
|
|
304
310
|
}
|
|
305
311
|
return lines.join('\n')
|
|
306
312
|
}
|
|
@@ -344,7 +350,8 @@ function describeRow(id, segmentText, children) {
|
|
|
344
350
|
const meta = ROW_META[id] ?? {}
|
|
345
351
|
// A literal `disabled: true` is off. A `!!js` predicate is resolved for THIS
|
|
346
352
|
// machine, so the page shows the state actually in force rather than "has a key".
|
|
347
|
-
|
|
353
|
+
// 只看"有没有 disabled 键"是不够的:`disabled: false` 也是字面量,但它表示**开着**。
|
|
354
|
+
const literalOff = own.present && !own.value.startsWith('!!js') && own.value === 'true'
|
|
348
355
|
const fromExpression = own.present ? evalDisabledExpression(own.value) : undefined
|
|
349
356
|
return {
|
|
350
357
|
id,
|
|
@@ -564,6 +571,15 @@ function flattenRows(rows, into = new Map()) {
|
|
|
564
571
|
return into
|
|
565
572
|
}
|
|
566
573
|
|
|
574
|
+
/** 同 {@link flattenRows},但保留整行对象:判断"未触碰"要看**文本形态**,不只是求值结果。 */
|
|
575
|
+
function flattenRowObjects(rows, into = new Map()) {
|
|
576
|
+
for (const row of rows) {
|
|
577
|
+
into.set(row.id, row)
|
|
578
|
+
flattenRowObjects(row.children, into)
|
|
579
|
+
}
|
|
580
|
+
return into
|
|
581
|
+
}
|
|
582
|
+
|
|
567
583
|
/**
|
|
568
584
|
* Derive the explicit overrides that turned `base` into `text`.
|
|
569
585
|
*
|
|
@@ -578,13 +594,19 @@ function flattenRows(rows, into = new Map()) {
|
|
|
578
594
|
* @returns {Record<string, boolean>} row id -> enabled.
|
|
579
595
|
*/
|
|
580
596
|
export function overridesOf(text, modeId) {
|
|
581
|
-
const base =
|
|
582
|
-
for (const extra of EXTRA_ROWS) base.set(extra.id, false)
|
|
583
|
-
const current =
|
|
597
|
+
const base = flattenRowObjects(collectRows(readBaseComposition(modeId)))
|
|
598
|
+
for (const extra of EXTRA_ROWS) base.set(extra.id, { id: extra.id, disabled: false, disabledExpression: null })
|
|
599
|
+
const current = flattenRowObjects(collectRows(text))
|
|
584
600
|
const overrides = {}
|
|
585
|
-
for (const [id,
|
|
586
|
-
|
|
587
|
-
|
|
601
|
+
for (const [id, row] of current) {
|
|
602
|
+
const baseRow = base.get(id)
|
|
603
|
+
// "未触碰"的判据是**文本形态相同**:出厂行可能是 `!!js` 平台表达式,而它在本机的求值结果恰好与
|
|
604
|
+
// 某个字面量一致 —— 只看求值结果,会把"表达式被换成字面量"误判成"没动过"。
|
|
605
|
+
const sameForm = baseRow !== undefined
|
|
606
|
+
&& baseRow.disabled === row.disabled
|
|
607
|
+
&& baseRow.disabledExpression === row.disabledExpression
|
|
608
|
+
if (sameForm) continue
|
|
609
|
+
overrides[id] = row.disabled !== true
|
|
588
610
|
}
|
|
589
611
|
return overrides
|
|
590
612
|
}
|
package/index.mjs
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
* rows the user changed by diffing against the same shipped base mode.
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
42
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
|
|
43
43
|
import { dirname, join } from 'node:path'
|
|
44
44
|
import { PROMPT_PATH, COMPOSITION_PATH, ROUTE_PATH, PRESET_DIR } from './paths.mjs'
|
|
45
45
|
import {
|
|
@@ -282,8 +282,8 @@ export function saveState(rows, input) {
|
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
try {
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
writeAtomic(compositionFile(directory), composition)
|
|
286
|
+
writeAtomic(promptFile(directory), prompt)
|
|
287
287
|
} catch (error) {
|
|
288
288
|
return { ok: false, error: '写入失败:' + describe(error) }
|
|
289
289
|
}
|
|
@@ -380,7 +380,7 @@ export function createAssistant(rows, input, templateDir = packagedPresetDir())
|
|
|
380
380
|
// The template ships a starter prompt; a duplicate replaces it with the source's.
|
|
381
381
|
if (source !== null) {
|
|
382
382
|
try {
|
|
383
|
-
|
|
383
|
+
writeAtomic(promptFile(created.dir), source.prompt)
|
|
384
384
|
} catch (error) {
|
|
385
385
|
return { ok: false, error: '写入提示词失败:' + describe(error) }
|
|
386
386
|
}
|
|
@@ -669,6 +669,19 @@ export function apply(ctx) {
|
|
|
669
669
|
})
|
|
670
670
|
}
|
|
671
671
|
|
|
672
|
+
/**
|
|
673
|
+
* 写文件:先写同目录的临时文件,再 rename 覆盖。
|
|
674
|
+
*
|
|
675
|
+
* `rename(2)` 在同一文件系统内是原子的,所以读者(提示词读取器按 mtime+size 缓存)要么看到旧内容、
|
|
676
|
+
* 要么看到新内容,不会读到写了一半的文件。原来连续两次 writeFileSync 在极端时序下可能被读成撕裂的
|
|
677
|
+
* prompt,而这个文件正是"用户的提示词"。
|
|
678
|
+
*/
|
|
679
|
+
function writeAtomic(file, text) {
|
|
680
|
+
const temporary = `${file}.tmp-${String(process.pid)}`
|
|
681
|
+
writeFileSync(temporary, text, 'utf8')
|
|
682
|
+
renameSync(temporary, file)
|
|
683
|
+
}
|
|
684
|
+
|
|
672
685
|
/** `error` as a readable string, without assuming it is an Error. */
|
|
673
686
|
function describe(error) {
|
|
674
687
|
return String((error && error.message) || error)
|
package/locales.mjs
CHANGED
|
@@ -67,14 +67,14 @@ export const zh = {
|
|
|
67
67
|
'name.descriptionPlaceholder': '模式描述(显示在模式选择器里,可留空)',
|
|
68
68
|
|
|
69
69
|
'mode.heading': '基础模式',
|
|
70
|
-
'mode.hint': '
|
|
70
|
+
'mode.hint': '选一个官方模式作为底子,下面再按行微调。注意:底子只决定**行集合**与工具能力 —— 本模式的 persona 行始终替换掉底子那一行(提示词由你编辑,complete: false),底子的提示词语义不会被继承。改完保存后,新建会话即生效,不需要重启。',
|
|
71
71
|
|
|
72
72
|
'rows.heading': '插件开关',
|
|
73
73
|
'rows.hint': '逐行控制这个模式挂载哪些插件,和官方插件列表一样按行铺开。没拨过的行保持官方默认(含平台判断);你手动拨了就以你的为准。',
|
|
74
74
|
|
|
75
75
|
'prompt.heading': '系统提示词',
|
|
76
76
|
'prompt.hint':
|
|
77
|
-
'
|
|
77
|
+
'这段文本在每个模型调用前重新读取,所以保存后下一步即生效,且只影响使用这个助手的会话。「导入」把文件读进编辑器(未保存前不写入任何东西);「导出」把当前文本存成 .md 文件。',
|
|
78
78
|
|
|
79
79
|
'status.enabled': '已启用',
|
|
80
80
|
'status.disabled': '已停用',
|
|
@@ -156,7 +156,7 @@ export const zh = {
|
|
|
156
156
|
'base.ptc.label': 'PTC 模式',
|
|
157
157
|
'base.ptc.note': '在标准模式基础上启用 PTC 工具呈现(tool-presentation)',
|
|
158
158
|
'base.minimal.label': '极简模式',
|
|
159
|
-
'base.minimal.note': '只有 Shell 与终端,共 7
|
|
159
|
+
'base.minimal.note': '只有 Shell 与终端,共 7 行;没有文件、检索、技能、子代理。系统提示词不是极简那一套(persona 行被本模式替换)',
|
|
160
160
|
'base.cordis.label': 'Cordis 模式',
|
|
161
161
|
'base.cordis.note': '标准模式 + 读写运行时的 Cordis 工具集,可让 agent 自己改 harness',
|
|
162
162
|
}
|
|
@@ -216,7 +216,7 @@ export const en = {
|
|
|
216
216
|
|
|
217
217
|
'mode.heading': 'Base mode',
|
|
218
218
|
'mode.hint':
|
|
219
|
-
'
|
|
219
|
+
'Pick an official mode as the base, then adjust it row by row. Note: the base only decides which rows exist — this mode always replaces the base\'s persona row with its own reader (complete: false), so the base\'s prompt semantics are not inherited. A save applies to the next new session; no restart needed.',
|
|
220
220
|
|
|
221
221
|
'rows.heading': 'Plugin switches',
|
|
222
222
|
'rows.hint':
|
|
@@ -224,7 +224,7 @@ export const en = {
|
|
|
224
224
|
|
|
225
225
|
'prompt.heading': 'System prompt',
|
|
226
226
|
'prompt.hint':
|
|
227
|
-
'This text is re-read before every model call, so a save applies on the next step
|
|
227
|
+
'This text is re-read before every model call, so a save applies on the next step and only affects sessions on this assistant. "Import" reads a file into the editor (nothing is written until you save); "Export" saves the current text as a .md file.',
|
|
228
228
|
|
|
229
229
|
'status.enabled': 'Enabled',
|
|
230
230
|
'status.disabled': 'Disabled',
|
|
@@ -306,7 +306,7 @@ export const en = {
|
|
|
306
306
|
'base.ptc.label': 'PTC',
|
|
307
307
|
'base.ptc.note': 'Standard plus PTC tool presentation (tool-presentation)',
|
|
308
308
|
'base.minimal.label': 'Minimal',
|
|
309
|
-
'base.minimal.note': 'Shell and terminal only, 7 rows; no files, search, skills or subagents',
|
|
309
|
+
'base.minimal.note': 'Shell and terminal only, 7 rows; no files, search, skills or subagents. The system prompt is not minimal\'s either (this mode replaces the persona row)',
|
|
310
310
|
'base.cordis.label': 'Cordis',
|
|
311
311
|
'base.cordis.note': 'Standard plus the Cordis toolset, letting the agent modify its own harness',
|
|
312
312
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-custom-mode",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Custom modes and custom prompts for DeepSeek Harness (dsh): edit a mode's system prompt on the settings page (it takes effect on the next model step), choose its base mode, switch plugins row by row, and keep several assistants side by side.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./index.mjs",
|
|
@@ -22,9 +22,18 @@
|
|
|
22
22
|
"keywords": [
|
|
23
23
|
"dsh",
|
|
24
24
|
"deepseek-harness",
|
|
25
|
+
"dsh-plugin",
|
|
26
|
+
"cordis",
|
|
25
27
|
"agent-preset",
|
|
28
|
+
"agent-mode",
|
|
29
|
+
"custom-mode",
|
|
30
|
+
"multi-mode",
|
|
31
|
+
"assistant",
|
|
26
32
|
"system-prompt",
|
|
27
|
-
"
|
|
33
|
+
"custom-prompt",
|
|
34
|
+
"prompt-editor",
|
|
35
|
+
"prompt-engineering",
|
|
36
|
+
"persona"
|
|
28
37
|
],
|
|
29
38
|
"dsh": {
|
|
30
39
|
"bundle": {
|
|
@@ -50,7 +59,7 @@
|
|
|
50
59
|
"test": "node ../test/run.mjs"
|
|
51
60
|
},
|
|
52
61
|
"peerDependencies": {
|
|
53
|
-
"@deepseek-ai/dsh": ">=0.1.6-alpha.1"
|
|
62
|
+
"@deepseek-ai/dsh": ">=0.1.6-alpha.1 <0.2.0-0"
|
|
54
63
|
},
|
|
55
64
|
"publishConfig": {
|
|
56
65
|
"access": "public",
|
|
@@ -62,6 +71,6 @@
|
|
|
62
71
|
}
|
|
63
72
|
},
|
|
64
73
|
"engines": {
|
|
65
|
-
"dsh": ">=0.1.6-alpha.1"
|
|
74
|
+
"dsh": ">=0.1.6-alpha.1 <0.2.0-0"
|
|
66
75
|
}
|
|
67
76
|
}
|