@chance722/dsh-inbox 0.2.0 → 0.2.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 CHANGED
@@ -60,14 +60,14 @@ Two questions in the same conversation, on a real machine:
60
60
 
61
61
  ## Install
62
62
 
63
- Requires Node ≥ 22 and a working `dsh` (`@deepseek-ai/dsh`).
63
+ Needs Node ≥ 22 and a working `dsh`. `dsh plugin add` forwards to pnpm, so the installer brings pnpm along when your machine does not have it:
64
64
 
65
65
  **Platform**: fully accepted on **Windows** only so far; macOS and Linux are **not verified yet** (no platform-specific dependency in the code — try it and tell me how it goes).
66
66
 
67
67
  `dsh web` is just `dsh --profile web`, so install into the profile you already start:
68
68
 
69
69
  ```powershell
70
- npx @chance722/dsh-inbox init --profile web
70
+ npx @chance722/dsh-inbox init --profile web --install-pnpm
71
71
  ```
72
72
 
73
73
  Then start dsh the way you always do — `dsh web`. The **Inbox** entry is in the left rail, and a new session's assistant can look things up for you ("what links in my inbox haven't I read yet?").
@@ -75,7 +75,7 @@ Then start dsh the way you always do — `dsh web`. The **Inbox** entry is in th
75
75
  On a machine that has never run dsh there is no `web` profile yet; `--create-profile` makes it first:
76
76
 
77
77
  ```powershell
78
- npx @chance722/dsh-inbox init --profile web --create-profile
78
+ npx @chance722/dsh-inbox init --profile web --create-profile --install-pnpm
79
79
  ```
80
80
 
81
81
  `init` does three things, and running it twice is safe:
@@ -93,7 +93,7 @@ npx @chance722/dsh-inbox init --create-profile # an isolated `inbox` profile
93
93
  dsh --profile inbox --no-open --port 3102 # start it there
94
94
  ```
95
95
 
96
- Other flags: `--profile <name>` installs elsewhere, `--no-default` leaves the default preset alone, `--help` lists everything. Which profile you install into only decides **where the panel runs** — the agent preset is shared by every profile (`~/.dsh/.agent-presets/inbox/`), so installing into a second one just fills in the missing row.
96
+ Other flags: `--profile <name>` installs elsewhere, `--install-pnpm` installs pnpm first when it is missing (the two commands above already carry it), `--no-default` leaves the default preset alone, `--help` lists everything. Which profile you install into only decides **where the panel runs** — the agent preset is shared by every profile (`~/.dsh/.agent-presets/inbox/`), so installing into a second one just fills in the missing row.
97
97
 
98
98
  ### From a local checkout
99
99
 
package/README.zh.md CHANGED
@@ -60,14 +60,14 @@
60
60
 
61
61
  ## 安装
62
62
 
63
- 前置:Node ≥ 22,以及一个能用的 `dsh`(`@deepseek-ai/dsh`)。
63
+ 前置:Node ≥ 22,以及一个能用的 `dsh`。`dsh plugin add` 是转发给 pnpm 的,所以机器上没有 pnpm 时,安装命令会顺手替你装好:
64
64
 
65
65
  **平台**:目前只在 **Windows** 上做过完整验收;macOS / Linux **尚未验证**(代码里没有平台特定依赖,欢迎试用后反馈)。
66
66
 
67
67
  `dsh web` 就是 `dsh --profile web`,所以直接装进你日常启动的那个 profile:
68
68
 
69
69
  ```powershell
70
- npx @chance722/dsh-inbox init --profile web
70
+ npx @chance722/dsh-inbox init --profile web --install-pnpm
71
71
  ```
72
72
 
73
73
  然后照旧启动——`dsh web`。左栏出现 **Inbox**;新会话里问「我的收件箱里有哪些还没看的链接」,助手就会去查。
@@ -75,7 +75,7 @@ npx @chance722/dsh-inbox init --profile web
75
75
  全新机器(从没跑过 dsh,还没有 `web` 这个 profile)加 `--create-profile` 让它先建:
76
76
 
77
77
  ```powershell
78
- npx @chance722/dsh-inbox init --profile web --create-profile
78
+ npx @chance722/dsh-inbox init --profile web --create-profile --install-pnpm
79
79
  ```
80
80
 
81
81
  `init` 做三件事,重复运行是安全的:
@@ -93,7 +93,7 @@ npx @chance722/dsh-inbox init --create-profile # 建一个隔离的 inbox pr
93
93
  dsh --profile inbox --no-open --port 3102 # 在那个 profile 里起
94
94
  ```
95
95
 
96
- 其它选项:`--profile <名字>` 装到别处,`--no-default` 不动默认 preset,`--help` 列全。装进哪个 profile 只决定**面板跑在哪儿**——agent preset 是所有 profile 共享的(`~/.dsh/.agent-presets/inbox/`),装第二个 profile 只会补上缺的那行。
96
+ 其它选项:`--profile <名字>` 装到别处,`--install-pnpm` 在没有 pnpm 时先替你装(上面两条命令已经带上它),`--no-default` 不动默认 preset,`--help` 列全。装进哪个 profile 只决定**面板跑在哪儿**——agent preset 是所有 profile 共享的(`~/.dsh/.agent-presets/inbox/`),装第二个 profile 只会补上缺的那行。
97
97
 
98
98
  ### 从本地仓库装
99
99
 
package/lib/cli.js CHANGED
@@ -36,6 +36,7 @@ function usage() {
36
36
  --create-profile profile \u4E0D\u5B58\u5728\u65F6\u7528 dsh \u81EA\u5E26\u7684 web \u6A21\u677F\u5EFA\u4E00\u4E2A\uFF08\u9ED8\u8BA4\u4E0D\u5F00\uFF09
37
37
  --preset <id> agent preset \u7684 id\uFF0C\u9ED8\u8BA4 inbox
38
38
  --package <\u6765\u6E90> \u63D2\u4EF6\u6765\u6E90\uFF0C\u9ED8\u8BA4 ${PACKAGE_NAME}\uFF08\u672C\u5730\u5F00\u53D1\u4F20\u4ED3\u5E93\u8DEF\u5F84\uFF09
39
+ --install-pnpm PATH \u4E0A\u6CA1\u6709 pnpm \u65F6\u66FF\u4F60\u88C5\uFF08\u5148 npm i -g pnpm\uFF0C\u4E0D\u884C\u518D\u8BD5 corepack\uFF09
39
40
  --no-default \u4E0D\u628A\u9ED8\u8BA4 preset \u6307\u8FC7\u53BB\uFF08\u53EA\u88C5\uFF0C\u4E0D\u6539 dsh \u7684\u9ED8\u8BA4\u9009\u62E9\uFF09
40
41
  --help \u8FD9\u4EFD\u8BF4\u660E
41
42
 
@@ -49,7 +50,8 @@ function parse(argv) {
49
50
  preset: "",
50
51
  source: PACKAGE_NAME,
51
52
  defaultPreset: true,
52
- createProfile: false
53
+ createProfile: false,
54
+ installPnpm: false
53
55
  };
54
56
  const rest = argv[0] === "init" ? argv.slice(1) : argv;
55
57
  for (let index = 0; index < rest.length; index += 1) {
@@ -68,6 +70,7 @@ function parse(argv) {
68
70
  else if (flag === "--package") options.source = value();
69
71
  else if (flag === "--no-default") options.defaultPreset = false;
70
72
  else if (flag === "--create-profile") options.createProfile = true;
73
+ else if (flag === "--install-pnpm") options.installPnpm = true;
71
74
  else throw new Error(`\u770B\u4E0D\u61C2\u7684\u9009\u9879\uFF1A${String(flag)}`);
72
75
  }
73
76
  if (options.preset.length === 0) options.preset = "inbox";
@@ -125,23 +128,42 @@ function dshHome() {
125
128
  const configured = process.env.DSH_HOME;
126
129
  return configured !== void 0 && configured.length > 0 ? configured : join(homedir(), ".dsh");
127
130
  }
128
- function shippedStandard(profileDir) {
131
+ function shippedStandard(home, profileDir) {
129
132
  const candidates = [];
133
+ const roster = (moduleRoot) => join(moduleRoot, "@deepseek-ai", "dsh-agent-presets");
134
+ const nestedRoster = (moduleRoot) => join(moduleRoot, "@deepseek-ai", "dsh", "node_modules", "@deepseek-ai", "dsh-agent-presets");
130
135
  try {
131
136
  const require2 = createRequire(join(profileDir, "package.json"));
132
137
  candidates.push(dirname(require2.resolve("@deepseek-ai/dsh-agent-presets/package.json")));
133
138
  } catch {
134
139
  }
135
140
  candidates.push(
136
- join(profileDir, "node_modules", "@deepseek-ai", "dsh-agent-presets"),
137
- join(profileDir, "node_modules", "@deepseek-ai", "dsh", "node_modules", "@deepseek-ai", "dsh-agent-presets")
141
+ roster(join(profileDir, "node_modules")),
142
+ nestedRoster(join(profileDir, "node_modules")),
143
+ roster(join(home, "profiles", "node_modules")),
144
+ nestedRoster(join(home, "profiles", "node_modules"))
138
145
  );
146
+ for (const prefix of dshPrefixes()) {
147
+ candidates.push(nestedRoster(join(prefix, "node_modules")), roster(join(prefix, "node_modules")));
148
+ }
139
149
  for (const candidate of candidates) {
140
150
  const standard = join(candidate, "presets", "standard");
141
151
  if (existsSync(join(standard, "agent.cordis.yml"))) return standard;
142
152
  }
143
153
  return void 0;
144
154
  }
155
+ function dshPrefixes() {
156
+ const found = spawnSync(process.platform === "win32" ? "where" : "which", ["dsh"], {
157
+ encoding: "utf8",
158
+ shell: process.platform === "win32"
159
+ });
160
+ const prefixes = [];
161
+ for (const line of (found.stdout ?? "").split(/\r?\n/)) {
162
+ const bin = line.trim();
163
+ if (bin.length > 0) prefixes.push(dirname(bin));
164
+ }
165
+ return prefixes;
166
+ }
145
167
  function setDefaultPreset(settingsPath, id) {
146
168
  const original = existsSync(settingsPath) ? readFileSync(settingsPath, "utf8") : "";
147
169
  const commit = (next, note) => {
@@ -203,8 +225,21 @@ function main(argv) {
203
225
  const profile = choice.profile;
204
226
  const chosen = choice.label.length === 0 ? "" : `\uFF08${choice.label}\uFF09`;
205
227
  const profileDir = join(home, "profiles", profile);
228
+ if (!hasPnpm()) {
229
+ if (!options.installPnpm) {
230
+ process.stderr.write(missingPnpmMessage(profile, options.source));
231
+ return 1;
232
+ }
233
+ process.stdout.write("\xB7 PATH \u4E0A\u6CA1\u6709 pnpm\uFF0C\u5148\u88C5\u4E00\u4E2A\uFF08--install-pnpm\uFF09\u2026\n");
234
+ if (!installPnpm()) {
235
+ process.stderr.write(missingPnpmMessage(profile, options.source));
236
+ return 1;
237
+ }
238
+ process.stdout.write(" pnpm \u88C5\u597D\u4E86\n");
239
+ }
206
240
  if (!existsSync(join(profileDir, "package.json"))) {
207
241
  const hint = `\u5148\u5EFA\u4E00\u4E2A\uFF1Adsh --profile ${profile} --from-default-profile web --dump-config
242
+ \uFF08profile \u540D\u662F dsh \u81EA\u5E26\u6A21\u677F\u65F6\u7528\uFF1Adsh --profile ${profile} --dump-config\uFF09
208
243
  \uFF08\u6216\u8005\u91CD\u8DD1\u65F6\u52A0\u4E0A --create-profile\uFF0C\u8BA9\u8FD9\u4E00\u6B65\u81EA\u5DF1\u53D1\u751F\uFF09
209
244
  `;
210
245
  if (!options.createProfile) {
@@ -212,22 +247,14 @@ function main(argv) {
212
247
  ${hint}`);
213
248
  return 1;
214
249
  }
215
- process.stdout.write(`\u24EA profile \u300C${profile}\u300D\u4E0D\u5B58\u5728\uFF0C\u7528 dsh \u7684 web \u6A21\u677F\u5EFA\u4E00\u4E2A\u2026
250
+ process.stdout.write(`\u24EA profile \u300C${profile}\u300D\u4E0D\u5B58\u5728\uFF0C\u7528 dsh \u81EA\u5E26\u7684\u6A21\u677F\u5EFA\u4E00\u4E2A\u2026
216
251
  `);
217
- const created = spawnSync(
218
- "dsh",
219
- ["--profile", profile, "--from-default-profile", "web", "--dump-config"],
220
- { encoding: "utf8", shell: process.platform === "win32" }
221
- );
222
- if (created.error !== void 0 || created.status !== 0 || !existsSync(join(profileDir, "package.json"))) {
223
- for (const stream of [created.stdout, created.stderr]) {
224
- if (typeof stream === "string" && stream.trim().length > 0) process.stderr.write(`${stream.trimEnd()}
252
+ const created = createProfile(profile);
253
+ if (!created.ok || !existsSync(join(profileDir, "package.json"))) {
254
+ if (created.output.trim().length > 0) process.stderr.write(`${created.output.trimEnd()}
225
255
  `);
226
- }
227
- process.stderr.write(
228
- `\u5EFA profile \u5931\u8D25${created.error === void 0 ? "" : `\uFF08${created.error.message}\uFF09`}\u3002
229
- ${hint}`
230
- );
256
+ process.stderr.write(`\u5EFA profile \u5931\u8D25\u3002
257
+ ${hint}`);
231
258
  return 1;
232
259
  }
233
260
  process.stdout.write(` \u5EFA\u597D\u4E86 ${profileDir}
@@ -247,7 +274,7 @@ ${hint}`
247
274
  );
248
275
  return 1;
249
276
  }
250
- const standard = shippedStandard(profileDir);
277
+ const standard = shippedStandard(home, profileDir);
251
278
  if (standard === void 0) {
252
279
  process.stderr.write("\u627E\u4E0D\u5230\u968F dsh \u9644\u5E26\u7684 standard preset\uFF0C\u65E0\u6CD5\u521B\u5EFA agent preset\u3002\n");
253
280
  return 1;
@@ -304,6 +331,57 @@ ${hint}`
304
331
  );
305
332
  return 0;
306
333
  }
334
+ function profileCreationAttempts(profile) {
335
+ return [
336
+ ["--profile", profile, "--from-default-profile", "web", "--dump-config"],
337
+ ["--profile", profile, "--dump-config"]
338
+ ];
339
+ }
340
+ function hasPnpm() {
341
+ const probe = spawnSync("pnpm", ["--version"], {
342
+ shell: process.platform === "win32",
343
+ stdio: "ignore"
344
+ });
345
+ return probe.error === void 0 && probe.status === 0;
346
+ }
347
+ function pnpmInstallAttempts() {
348
+ return [
349
+ ["npm", "i", "-g", "pnpm"],
350
+ ["corepack", "enable", "pnpm"]
351
+ ];
352
+ }
353
+ function installPnpm() {
354
+ for (const args of pnpmInstallAttempts()) {
355
+ const command = args.join(" ");
356
+ process.stdout.write(` ${command} \u2026
357
+ `);
358
+ const run = spawnSync(args[0], [...args].slice(1), {
359
+ stdio: "inherit",
360
+ shell: process.platform === "win32"
361
+ });
362
+ if (run.error === void 0 && run.status === 0 && hasPnpm()) return true;
363
+ }
364
+ return false;
365
+ }
366
+ function missingPnpmMessage(profile, source) {
367
+ return `\u88C5\u63D2\u4EF6\u9700\u8981 pnpm\uFF1Adsh \u7684 \`plugin add\` \u662F\u8F6C\u53D1\u7ED9 pnpm \u7684\uFF08\u4E0D\u662F\u672C\u547D\u4EE4\u7684\u9009\u62E9\uFF09\u3002
368
+ \u8981\u4E48\u81EA\u5DF1\u88C5\uFF1Anpm i -g pnpm \uFF08\u6216\u8005\uFF1Acorepack enable pnpm\uFF09
369
+ \u8981\u4E48\u91CD\u8DD1\u65F6\u52A0\u4E0A --install-pnpm\uFF0C\u8BA9\u672C\u547D\u4EE4\u66FF\u4F60\u88C5\u3002
370
+ \u624B\u52A8\u7B49\u4EF7\u547D\u4EE4\uFF1Adsh plugin --profile ${profile} add ${source}
371
+ `;
372
+ }
373
+ function createProfile(profile) {
374
+ let output = "";
375
+ for (const args of profileCreationAttempts(profile)) {
376
+ const run = spawnSync("dsh", [...args], {
377
+ encoding: "utf8",
378
+ shell: process.platform === "win32"
379
+ });
380
+ output = `${run.stdout ?? ""}${run.stderr ?? ""}`;
381
+ if (run.error === void 0 && run.status === 0) return { ok: true, output };
382
+ }
383
+ return { ok: false, output };
384
+ }
307
385
  if (isEntryPoint(import.meta.url, process.argv[1])) {
308
386
  process.exitCode = main(process.argv.slice(2));
309
387
  }
@@ -312,5 +390,8 @@ export {
312
390
  ensurePresetRow,
313
391
  isEntryPoint,
314
392
  listProfiles,
315
- parse
393
+ missingPnpmMessage,
394
+ parse,
395
+ pnpmInstallAttempts,
396
+ profileCreationAttempts
316
397
  };
package/lib/index.js CHANGED
@@ -3,7 +3,7 @@ import { defineTool as defineTool2 } from "@deepseek-ai/dsh-tools";
3
3
 
4
4
  // src/shared/constants.ts
5
5
  var PACKAGE_NAME = "@chance722/dsh-inbox";
6
- var VERSION = true ? "0.2.0" : "0.0.0-dev";
6
+ var VERSION = true ? "0.2.2" : "0.0.0-dev";
7
7
  var DEFAULT_USER_AGENT = "dsh-inbox";
8
8
 
9
9
  // src/shared/vocabulary.ts
@@ -48,6 +48,8 @@ export interface Options {
48
48
  defaultPreset: boolean;
49
49
  /** Create the profile when it is missing, instead of refusing. */
50
50
  createProfile: boolean;
51
+ /** Install pnpm when it is missing, instead of stopping to explain it. */
52
+ installPnpm: boolean;
51
53
  }
52
54
  export declare function parse(argv: readonly string[]): Options | undefined;
53
55
  /**
@@ -99,3 +101,44 @@ export declare function chooseProfile(options: Pick<Options, 'profile' | 'create
99
101
  * @returns true when `entry` is this very file.
100
102
  */
101
103
  export declare function isEntryPoint(moduleUrl: string, entry: string | undefined): boolean;
104
+ /**
105
+ * The commands that can create a missing profile, in the order to try them.
106
+ *
107
+ * A *shipped* template cannot be the target of `--from-default-profile`: dsh
108
+ * refuses with `profile "web" is shipped and cannot be a custom profile target;
109
+ * omit --from-default-profile to use it`. `init --profile web --create-profile`
110
+ * on a machine that has never run dsh is exactly that case — and since choosing
111
+ * `web` is what this installer now does by default, that would have been the
112
+ * *first* thing a new user hit (measured 2026-09-20, on a fresh `%DSH_HOME%`,
113
+ * before 0.2.0 shipped). The bare form is also the one that initializes a
114
+ * shipped profile at all, so it is the fallback rather than the first choice.
115
+ *
116
+ * Both forms are tried instead of special-casing `web`: `headless` is shipped
117
+ * too, and a future template should not need this file to change.
118
+ *
119
+ * @param profile - the profile to create.
120
+ * @returns argv lists for `dsh`, most specific first.
121
+ */
122
+ export declare function profileCreationAttempts(profile: string): readonly (readonly string[])[];
123
+ /**
124
+ * The commands that can put pnpm on PATH, in the order to try them.
125
+ *
126
+ * `npm i -g pnpm` first because whoever ran `npx` has npm by definition and
127
+ * knows where its global shims land. `corepack enable pnpm` is the fallback:
128
+ * no download, but it needs a Node that still ships corepack (Node ≥ 25 does
129
+ * not), so it cannot be the first choice.
130
+ *
131
+ * @returns argv lists, most likely to work first.
132
+ */
133
+ export declare function pnpmInstallAttempts(): readonly (readonly string[])[];
134
+ /**
135
+ * What to say when there is no pnpm to hand.
136
+ *
137
+ * Exported because the wording is the whole value here: the point is that the
138
+ * reader can act on it without knowing which part of the chain wanted pnpm.
139
+ *
140
+ * @param profile - the profile that was about to receive the plugin.
141
+ * @param source - the package (or path) that was about to be installed.
142
+ * @returns the message, ending in the command to run by hand.
143
+ */
144
+ export declare function missingPnpmMessage(profile: string, source: string): string;
package/package.json CHANGED
@@ -1,101 +1,101 @@
1
- {
2
- "name": "@chance722/dsh-inbox",
3
- "version": "0.2.0",
4
- "private": false,
5
- "description": "Personal paste inbox for DeepSeek Harness (dsh): capture, classify, browse and retrieve.",
6
- "keywords": [
7
- "dsh",
8
- "dsh-plugin",
9
- "deepseek-harness",
10
- "inbox",
11
- "clipboard",
12
- "vault"
13
- ],
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://github.com/Chance722/dsh-inbox.git"
17
- },
18
- "homepage": "https://github.com/Chance722/dsh-inbox#readme",
19
- "bugs": {
20
- "url": "https://github.com/Chance722/dsh-inbox/issues"
21
- },
22
- "publishConfig": {
23
- "access": "public"
24
- },
25
- "type": "module",
26
- "license": "MIT",
27
- "main": "lib/index.js",
28
- "types": "lib/types/host/index.d.ts",
29
- "exports": {
30
- ".": {
31
- "types": "./lib/types/host/index.d.ts",
32
- "default": "./lib/index.js"
33
- },
34
- "./client": {
35
- "types": "./lib/types/client/index.d.ts",
36
- "default": "./lib/client.js"
37
- },
38
- "./package.json": "./package.json"
39
- },
40
- "files": [
41
- "lib/index.js",
42
- "lib/client.js",
43
- "lib/cli.js",
44
- "cordis.patch.yml",
45
- "lib/types/**/*.d.ts"
46
- ],
47
- "bin": {
48
- "dsh-inbox": "./lib/cli.js"
49
- },
50
- "dsh": {
51
- "bundle": {
52
- "patch": "./cordis.patch.yml"
53
- },
54
- "client": {
55
- "platform": "web",
56
- "inject": [
57
- "@deepseek-ai/dsh-client-connection",
58
- "@deepseek-ai/dsh-client-ui-layout",
59
- "@deepseek-ai/dsh-client-ui-sidebar"
60
- ]
61
- }
62
- },
63
- "scripts": {
64
- "build": "node scripts/build.mjs && tsc -p tsconfig.build.json",
65
- "typecheck": "tsc --noEmit",
66
- "test": "vitest run",
1
+ {
2
+ "name": "@chance722/dsh-inbox",
3
+ "version": "0.2.2",
4
+ "private": false,
5
+ "description": "Personal paste inbox for DeepSeek Harness (dsh): capture, classify, browse and retrieve.",
6
+ "keywords": [
7
+ "dsh",
8
+ "dsh-plugin",
9
+ "deepseek-harness",
10
+ "inbox",
11
+ "clipboard",
12
+ "vault"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/Chance722/dsh-inbox.git"
17
+ },
18
+ "homepage": "https://github.com/Chance722/dsh-inbox#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/Chance722/dsh-inbox/issues"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "type": "module",
26
+ "license": "MIT",
27
+ "main": "lib/index.js",
28
+ "types": "lib/types/host/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./lib/types/host/index.d.ts",
32
+ "default": "./lib/index.js"
33
+ },
34
+ "./client": {
35
+ "types": "./lib/types/client/index.d.ts",
36
+ "default": "./lib/client.js"
37
+ },
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "lib/index.js",
42
+ "lib/client.js",
43
+ "lib/cli.js",
44
+ "cordis.patch.yml",
45
+ "lib/types/**/*.d.ts"
46
+ ],
47
+ "bin": {
48
+ "dsh-inbox": "./lib/cli.js"
49
+ },
50
+ "dsh": {
51
+ "bundle": {
52
+ "patch": "./cordis.patch.yml"
53
+ },
54
+ "client": {
55
+ "platform": "web",
56
+ "inject": [
57
+ "@deepseek-ai/dsh-client-connection",
58
+ "@deepseek-ai/dsh-client-ui-layout",
59
+ "@deepseek-ai/dsh-client-ui-sidebar"
60
+ ]
61
+ }
62
+ },
63
+ "scripts": {
64
+ "build": "node scripts/build.mjs && tsc -p tsconfig.build.json",
65
+ "typecheck": "tsc --noEmit",
66
+ "test": "vitest run",
67
67
  "prepublishOnly": "npm run build"
68
- },
69
- "dependencies": {
70
- "lucide-react": "^1.47.0",
71
- "zod": "^4.4.3"
72
- },
73
- "peerDependencies": {
74
- "@deepseek-ai/cordis": "^4.0.2",
75
- "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2",
76
- "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
77
- "@deepseek-ai/dsh-commands": "^0.1.5-rc.2",
78
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
79
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
80
- "@deepseek-ai/dsh-web": "^0.1.5-rc.2"
81
- },
82
- "devDependencies": {
83
- "@deepseek-ai/cordis": "^4.0.2",
84
- "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2",
85
- "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
86
- "@deepseek-ai/dsh-commands": "^0.1.5-rc.2",
87
- "@deepseek-ai/dsh-storage": "^0.1.5-rc.2",
88
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
89
- "@deepseek-ai/dsh-storage-json": "^0.1.5-rc.2",
90
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
91
- "@deepseek-ai/dsh-web": "0.1.5-rc.2",
92
- "@deepseek-ai/schemastery": "3.18.2",
93
- "@types/node": "^22.10.0",
94
- "@types/react": "~18.3.1",
95
- "esbuild": "^0.25.0",
96
- "react": "^18.2.0",
97
- "typescript": "^5.7.0",
98
- "vitest": "^3.0.0",
99
- "zod": "^4.4.3"
100
- }
101
- }
68
+ },
69
+ "dependencies": {
70
+ "lucide-react": "^1.47.0",
71
+ "zod": "^4.4.3"
72
+ },
73
+ "peerDependencies": {
74
+ "@deepseek-ai/cordis": "^4.0.2",
75
+ "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2",
76
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
77
+ "@deepseek-ai/dsh-commands": "^0.1.5-rc.2",
78
+ "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
79
+ "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
80
+ "@deepseek-ai/dsh-web": "^0.1.5-rc.2"
81
+ },
82
+ "devDependencies": {
83
+ "@deepseek-ai/cordis": "^4.0.2",
84
+ "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2",
85
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
86
+ "@deepseek-ai/dsh-commands": "^0.1.5-rc.2",
87
+ "@deepseek-ai/dsh-storage": "^0.1.5-rc.2",
88
+ "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
89
+ "@deepseek-ai/dsh-storage-json": "^0.1.5-rc.2",
90
+ "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
91
+ "@deepseek-ai/dsh-web": "0.1.5-rc.2",
92
+ "@deepseek-ai/schemastery": "3.18.2",
93
+ "@types/node": "^22.10.0",
94
+ "@types/react": "~18.3.1",
95
+ "esbuild": "^0.25.0",
96
+ "react": "^18.2.0",
97
+ "typescript": "^5.7.0",
98
+ "vitest": "^3.0.0",
99
+ "zod": "^4.4.3"
100
+ }
101
+ }