dsh-pixel-ui 1.5.1 → 1.8.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.
Files changed (38) hide show
  1. package/LICENSE +29 -21
  2. package/README.md +113 -22
  3. package/assets/complete-ui/hologram/ATTRIBUTION.md +17 -0
  4. package/assets/complete-ui/hologram/LICENSE.txt +20 -0
  5. package/assets/complete-ui/hologram/button-primary-lock.png +0 -0
  6. package/assets/complete-ui/hologram/button-primary-press.png +0 -0
  7. package/assets/complete-ui/hologram/button-primary.png +0 -0
  8. package/assets/complete-ui/hologram/icon-button.png +0 -0
  9. package/assets/complete-ui/hologram/input.png +0 -0
  10. package/assets/complete-ui/hologram/panel.png +0 -0
  11. package/assets/complete-ui/hologram/scroll-handle.png +0 -0
  12. package/assets/complete-ui/hologram/select-bar.png +0 -0
  13. package/assets/complete-ui/papernote/ATTRIBUTION.md +28 -0
  14. package/assets/complete-ui/papernote/LICENSE.txt +20 -0
  15. package/assets/complete-ui/papernote/button-hover.png +0 -0
  16. package/assets/complete-ui/papernote/button.png +0 -0
  17. package/assets/complete-ui/papernote/cursor.png +0 -0
  18. package/assets/complete-ui/papernote/icon-button.png +0 -0
  19. package/assets/complete-ui/papernote/input.png +0 -0
  20. package/assets/complete-ui/papernote/panel.png +0 -0
  21. package/assets/complete-ui/papernote/popover.png +0 -0
  22. package/assets/complete-ui/pumpkin/ATTRIBUTION.md +34 -0
  23. package/assets/complete-ui/pumpkin/LICENSE.txt +20 -0
  24. package/assets/complete-ui/pumpkin/button-hover.png +0 -0
  25. package/assets/complete-ui/pumpkin/button-press.png +0 -0
  26. package/assets/complete-ui/pumpkin/button.png +0 -0
  27. package/assets/complete-ui/pumpkin/icon-button.png +0 -0
  28. package/assets/complete-ui/pumpkin/input.png +0 -0
  29. package/assets/complete-ui/pumpkin/panel.png +0 -0
  30. package/assets/complete-ui/pumpkin/popover.png +0 -0
  31. package/assets/complete-ui/pumpkin/select.png +0 -0
  32. package/assets/preview-hologram.png +0 -0
  33. package/assets/preview-papernote.png +0 -0
  34. package/assets/preview-pumpkin.png +0 -0
  35. package/lib/client.js +1591 -7
  36. package/lib/client.js.map +2 -2
  37. package/lib/index.js +172 -167
  38. package/package.json +81 -81
package/lib/index.js CHANGED
@@ -1,167 +1,172 @@
1
- /**
2
- * dsh-pixel-ui — node half.
3
- *
4
- * Serves the bundled pixel fonts to the browser half under
5
- * `/dsh-pixel-ui/fonts/<file>` (filename whitelist — no path traversal) and
6
- * persists the selected theme under `$DSH_HOME/storages/dsh-pixel-ui/preference.json`
7
- * behind `/dsh-pixel-ui/preference` (GET reads, PUT writes).
8
- *
9
- * The durable preference is what fixes DSH Desktop's random local port: the
10
- * browser half keys `localStorage` per origin (including the port), so a
11
- * per-launch port forgot the chosen skin on every restart. The host file is
12
- * port-independent, and the browser half prefers it over its local mirror.
13
- *
14
- * @module dsh-pixel-ui
15
- */
16
- import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
17
- import { join } from 'node:path'
18
- import { fileURLToPath } from 'node:url'
19
- import { resolveDshHome } from '@deepseek-ai/dsh-home-paths'
20
-
21
- /** Plugin name; also the patch row id. */
22
- export const name = 'dsh-pixel-ui'
23
-
24
- /** Required services: the web route registry. */
25
- export const inject = ['webServer']
26
-
27
- const FONTS_DIR = fileURLToPath(new URL('../assets/fonts/', import.meta.url))
28
-
29
- const FONT_TYPES = {
30
- 'fusion-pixel-12px.woff2': 'font/woff2',
31
- 'PressStart2P-Regular.ttf': 'font/ttf',
32
- }
33
-
34
- /** Built-in preference ids plus this plugin's own pixel ids. */
35
- const BUILTIN_IDS = new Set(['light', 'dark', 'system'])
36
-
37
- /** Theme ids accepted from the wire: built-ins or `pixel-*`. */
38
- function normalizeTheme(value) {
39
- if (typeof value !== 'string') return null
40
- const id = value.trim()
41
- if (BUILTIN_IDS.has(id) || /^pixel-[a-z0-9-]{1,48}$/.test(id)) return id
42
- return null
43
- }
44
-
45
- const PREFERENCE_DIR = join(resolveDshHome(), 'storages', 'dsh-pixel-ui')
46
- const PREFERENCE_FILE = join(PREFERENCE_DIR, 'preference.json')
47
-
48
- /**
49
- * Page-bootstrap global carrying the durable preference.
50
- *
51
- * DSH Desktop renders the page from `dsh-app://app/`, so a same-origin
52
- * relative fetch of the preference route (the Web deployment's transport)
53
- * cannot work there. The Host knows the value before the first paint, so the
54
- * index injection is the one transport that exists in both deployments.
55
- */
56
- const BOOTSTRAP_GLOBAL = '__DSH_PIXEL_UI__'
57
-
58
- /** Read the durable preference; missing or corrupt files read as unset. */
59
- function readPreference() {
60
- try {
61
- const parsed = JSON.parse(readFileSync(PREFERENCE_FILE, 'utf8'))
62
- return normalizeTheme(parsed?.theme)
63
- } catch {
64
- return null
65
- }
66
- }
67
-
68
- /** Atomically persist the preference (tmp + rename). Storage failures are non-fatal. */
69
- function writePreference(theme) {
70
- try {
71
- mkdirSync(PREFERENCE_DIR, { recursive: true })
72
- const tmp = `${PREFERENCE_FILE}.${process.pid}.tmp`
73
- writeFileSync(tmp, `${JSON.stringify({ theme })}\n`)
74
- renameSync(tmp, PREFERENCE_FILE)
75
- return true
76
- } catch {
77
- return false
78
- }
79
- }
80
-
81
- /** Collect a JSON request body with a hard size cap. */
82
- function readJsonBody(req, limitBytes = 2048) {
83
- return new Promise((resolve, reject) => {
84
- const chunks = []
85
- let size = 0
86
- req.on('data', (chunk) => {
87
- size += chunk.length
88
- if (size > limitBytes) {
89
- reject(new Error('body too large'))
90
- req.destroy()
91
- return
92
- }
93
- chunks.push(chunk)
94
- })
95
- req.on('end', () => {
96
- try { resolve(JSON.parse(Buffer.concat(chunks).toString('utf8'))) }
97
- catch (error) { reject(error) }
98
- })
99
- req.on('error', reject)
100
- })
101
- }
102
-
103
- const json = (res, status, payload) => {
104
- res.writeHead(status, {
105
- 'content-type': 'application/json; charset=utf-8',
106
- 'cache-control': 'no-store',
107
- })
108
- res.end(JSON.stringify(payload))
109
- }
110
-
111
- /**
112
- * Mount the plugin routes: the font prefix and the preference endpoint.
113
- * @param ctx - context carrying webServer.
114
- */
115
- export function apply(ctx) {
116
- ctx.effect(() => ctx.webServer.register({
117
- kind: 'prefix',
118
- path: '/dsh-pixel-ui/fonts',
119
- handler: (req, res) => {
120
- const pathname = new URL(req.url ?? '/', 'http://x').pathname
121
- const file = pathname.slice('/dsh-pixel-ui/fonts/'.length)
122
- const type = FONT_TYPES[file]
123
- if (type === undefined) {
124
- res.writeHead(404)
125
- res.end()
126
- return
127
- }
128
- res.writeHead(200, {
129
- 'content-type': type,
130
- 'cache-control': 'public, max-age=86400',
131
- })
132
- res.end(readFileSync(join(FONTS_DIR, file)))
133
- },
134
- }), 'dsh-pixel-ui: fonts route')
135
-
136
- ctx.effect(() => ctx.webServer.register({
137
- kind: 'exact',
138
- path: '/dsh-pixel-ui/preference',
139
- handler: async (req, res) => {
140
- if (req.method === 'GET' || req.method === 'HEAD') {
141
- json(res, 200, { theme: readPreference() })
142
- return
143
- }
144
- if (req.method === 'PUT' || req.method === 'POST') {
145
- let theme = null
146
- try {
147
- const body = await readJsonBody(req)
148
- theme = normalizeTheme(body?.theme)
149
- } catch {
150
- json(res, 400, { error: 'invalid json body' })
151
- return
152
- }
153
- if (theme === null || !writePreference(theme)) {
154
- json(res, 400, { error: 'theme must be light, dark, system or pixel-*' })
155
- return
156
- }
157
- json(res, 200, { theme })
158
- return
159
- }
160
- json(res, 405, { error: 'method not allowed' })
161
- },
162
- }), 'dsh-pixel-ui: preference route')
163
-
164
- ctx.effect(() => ctx.on('webserver/index-inject', (table) => {
165
- table.push({ kind: 'global', name: BOOTSTRAP_GLOBAL, value: { theme: readPreference() } })
166
- }), 'dsh-pixel-ui: boot preference injection')
167
- }
1
+ /**
2
+ * dsh-pixel-ui — node half.
3
+ *
4
+ * Serves the bundled pixel fonts under `/dsh-pixel-ui/fonts/<file>` (filename
5
+ * whitelist — no path traversal) and persists the selected theme under
6
+ * `$DSH_HOME/storages/dsh-pixel-ui/preference.json` behind
7
+ * `/dsh-pixel-ui/preference` (GET reads, PUT writes).
8
+ *
9
+ * The 9-slice sprites of the asset themes (Hologram / Pumpkin / Papernote) are
10
+ * NOT served here: the build inlines them into `lib/client.js` as data URIs
11
+ * (`scripts/asset-inline.mjs`), so a sprite update needs only a page refresh
12
+ * and never another host route.
13
+ *
14
+ * The durable preference is what fixes DSH Desktop's random local port: the
15
+ * browser half keys `localStorage` per origin (including the port), so a
16
+ * per-launch port forgot the chosen skin on every restart. The host file is
17
+ * port-independent, and the browser half prefers it over its local mirror.
18
+ *
19
+ * @module dsh-pixel-ui
20
+ */
21
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
22
+ import { join } from 'node:path'
23
+ import { fileURLToPath } from 'node:url'
24
+ import { resolveDshHome } from '@deepseek-ai/dsh-home-paths'
25
+
26
+ /** Plugin name; also the patch row id. */
27
+ export const name = 'dsh-pixel-ui'
28
+
29
+ /** Required services: the web route registry. */
30
+ export const inject = ['webServer']
31
+
32
+ const FONTS_DIR = fileURLToPath(new URL('../assets/fonts/', import.meta.url))
33
+
34
+ const FONT_TYPES = {
35
+ 'fusion-pixel-12px.woff2': 'font/woff2',
36
+ 'PressStart2P-Regular.ttf': 'font/ttf',
37
+ }
38
+
39
+ /** Built-in preference ids plus this plugin's own pixel ids. */
40
+ const BUILTIN_IDS = new Set(['light', 'dark', 'system'])
41
+
42
+ /** Theme ids accepted from the wire: built-ins or `pixel-*`. */
43
+ function normalizeTheme(value) {
44
+ if (typeof value !== 'string') return null
45
+ const id = value.trim()
46
+ if (BUILTIN_IDS.has(id) || /^pixel-[a-z0-9-]{1,48}$/.test(id)) return id
47
+ return null
48
+ }
49
+
50
+ const PREFERENCE_DIR = join(resolveDshHome(), 'storages', 'dsh-pixel-ui')
51
+ const PREFERENCE_FILE = join(PREFERENCE_DIR, 'preference.json')
52
+
53
+ /**
54
+ * Page-bootstrap global carrying the durable preference.
55
+ *
56
+ * DSH Desktop renders the page from `dsh-app://app/`, so a same-origin
57
+ * relative fetch of the preference route (the Web deployment's transport)
58
+ * cannot work there. The Host knows the value before the first paint, so the
59
+ * index injection is the one transport that exists in both deployments.
60
+ */
61
+ const BOOTSTRAP_GLOBAL = '__DSH_PIXEL_UI__'
62
+
63
+ /** Read the durable preference; missing or corrupt files read as unset. */
64
+ function readPreference() {
65
+ try {
66
+ const parsed = JSON.parse(readFileSync(PREFERENCE_FILE, 'utf8'))
67
+ return normalizeTheme(parsed?.theme)
68
+ } catch {
69
+ return null
70
+ }
71
+ }
72
+
73
+ /** Atomically persist the preference (tmp + rename). Storage failures are non-fatal. */
74
+ function writePreference(theme) {
75
+ try {
76
+ mkdirSync(PREFERENCE_DIR, { recursive: true })
77
+ const tmp = `${PREFERENCE_FILE}.${process.pid}.tmp`
78
+ writeFileSync(tmp, `${JSON.stringify({ theme })}\n`)
79
+ renameSync(tmp, PREFERENCE_FILE)
80
+ return true
81
+ } catch {
82
+ return false
83
+ }
84
+ }
85
+
86
+ /** Collect a JSON request body with a hard size cap. */
87
+ function readJsonBody(req, limitBytes = 2048) {
88
+ return new Promise((resolve, reject) => {
89
+ const chunks = []
90
+ let size = 0
91
+ req.on('data', (chunk) => {
92
+ size += chunk.length
93
+ if (size > limitBytes) {
94
+ reject(new Error('body too large'))
95
+ req.destroy()
96
+ return
97
+ }
98
+ chunks.push(chunk)
99
+ })
100
+ req.on('end', () => {
101
+ try { resolve(JSON.parse(Buffer.concat(chunks).toString('utf8'))) }
102
+ catch (error) { reject(error) }
103
+ })
104
+ req.on('error', reject)
105
+ })
106
+ }
107
+
108
+ const json = (res, status, payload) => {
109
+ res.writeHead(status, {
110
+ 'content-type': 'application/json; charset=utf-8',
111
+ 'cache-control': 'no-store',
112
+ })
113
+ res.end(JSON.stringify(payload))
114
+ }
115
+
116
+ /**
117
+ * Mount the plugin routes: the font prefix and the preference endpoint.
118
+ * @param ctx - context carrying webServer.
119
+ */
120
+ export function apply(ctx) {
121
+ ctx.effect(() => ctx.webServer.register({
122
+ kind: 'prefix',
123
+ path: '/dsh-pixel-ui/fonts',
124
+ handler: (req, res) => {
125
+ const pathname = new URL(req.url ?? '/', 'http://x').pathname
126
+ const file = pathname.slice('/dsh-pixel-ui/fonts/'.length)
127
+ const type = FONT_TYPES[file]
128
+ if (type === undefined) {
129
+ res.writeHead(404)
130
+ res.end()
131
+ return
132
+ }
133
+ res.writeHead(200, {
134
+ 'content-type': type,
135
+ 'cache-control': 'public, max-age=86400',
136
+ })
137
+ res.end(readFileSync(join(FONTS_DIR, file)))
138
+ },
139
+ }), 'dsh-pixel-ui: fonts route')
140
+
141
+ ctx.effect(() => ctx.webServer.register({
142
+ kind: 'exact',
143
+ path: '/dsh-pixel-ui/preference',
144
+ handler: async (req, res) => {
145
+ if (req.method === 'GET' || req.method === 'HEAD') {
146
+ json(res, 200, { theme: readPreference() })
147
+ return
148
+ }
149
+ if (req.method === 'PUT' || req.method === 'POST') {
150
+ let theme = null
151
+ try {
152
+ const body = await readJsonBody(req)
153
+ theme = normalizeTheme(body?.theme)
154
+ } catch {
155
+ json(res, 400, { error: 'invalid json body' })
156
+ return
157
+ }
158
+ if (theme === null || !writePreference(theme)) {
159
+ json(res, 400, { error: 'theme must be light, dark, system or pixel-*' })
160
+ return
161
+ }
162
+ json(res, 200, { theme })
163
+ return
164
+ }
165
+ json(res, 405, { error: 'method not allowed' })
166
+ },
167
+ }), 'dsh-pixel-ui: preference route')
168
+
169
+ ctx.effect(() => ctx.on('webserver/index-inject', (table) => {
170
+ table.push({ kind: 'global', name: BOOTSTRAP_GLOBAL, value: { theme: readPreference() } })
171
+ }), 'dsh-pixel-ui: boot preference injection')
172
+ }
package/package.json CHANGED
@@ -1,81 +1,81 @@
1
- {
2
- "name": "dsh-pixel-ui",
3
- "version": "1.5.1",
4
- "description": "DSH 像素皮肤:Agent Xi 风格四主题(木屋/羊皮纸/暖阳/终端绿)+ fusion-pixel/Press Start 2P 像素字体;完全平面(无立体/无阴影)、整像素描边、内容列宽随视口撑开;宿主侧记忆主题选择,桌面端 dsh-app:// 也能恢复",
5
- "type": "module",
6
- "main": "lib/index.js",
7
- "files": [
8
- "lib",
9
- "assets",
10
- "cordis.patch.yml",
11
- "README.md",
12
- "LICENSE"
13
- ],
14
- "exports": {
15
- ".": "./lib/index.js",
16
- "./client": "./lib/client.js",
17
- "./package.json": "./package.json"
18
- },
19
- "scripts": {
20
- "build": "node scripts/build.mjs",
21
- "test": "node scripts/check-compat.mjs && node scripts/test-host.mjs && node scripts/test-client.mjs && node scripts/audit-contrast.mjs",
22
- "test:compat": "node scripts/check-compat.mjs",
23
- "test:host": "node scripts/test-host.mjs",
24
- "test:client": "node scripts/test-client.mjs",
25
- "test:contrast": "node scripts/audit-contrast.mjs"
26
- },
27
- "repository": {
28
- "type": "git",
29
- "url": "git+https://github.com/zhang66633/dsh-pixel-ui.git"
30
- },
31
- "keywords": [
32
- "dsh",
33
- "dsh-plugin",
34
- "deepseek-harness",
35
- "theme",
36
- "skin",
37
- "pixel",
38
- "retro",
39
- "ui"
40
- ],
41
- "engines": {
42
- "dsh": ">=0.1.0-rc.6 <0.2.0-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0"
43
- },
44
- "dsh": {
45
- "bundle": {
46
- "patch": "./cordis.patch.yml"
47
- },
48
- "client": {
49
- "inject": [
50
- "@deepseek-ai/dsh-client-ui-theme",
51
- "@deepseek-ai/dsh-client-ui-slots",
52
- "@deepseek-ai/dsh-client-ui-settings-general"
53
- ],
54
- "platform": "web"
55
- },
56
- "compatibility": {
57
- "dsh": ">=0.1.0-rc.6 <0.3.0-0",
58
- "dshReleases": {
59
- "0.1.0-rc.6": "compatible",
60
- "0.1.0-rc.7": "compatible",
61
- "0.1.7-rc.2": "compatible",
62
- "0.2.0-rc.1": "compatible",
63
- "0.2.0-rc.2": "compatible",
64
- "0.2.1-rc.3": "compatible"
65
- }
66
- }
67
- },
68
- "peerDependencies": {
69
- "@deepseek-ai/cordis": "^4.0.1",
70
- "@deepseek-ai/dsh-client-store": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
71
- "@deepseek-ai/dsh-client-ui-theme": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
72
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
73
- "@deepseek-ai/dsh-client-ui-settings-general": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
74
- "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0"
75
- },
76
- "devDependencies": {
77
- "esbuild": "^0.28.2",
78
- "semver": "^7.8.5"
79
- },
80
- "license": "MIT"
81
- }
1
+ {
2
+ "name": "dsh-pixel-ui",
3
+ "version": "1.8.1",
4
+ "description": "DSH 像素皮肤:Agent Xi 风格七主题(木屋/羊皮纸/暖阳/终端绿/全息/南瓜灯/便签本)+ fusion-pixel/Press Start 2P 像素字体;三套真素材主题用 Complete UI 的 9-slice PNG(构建期内联,离线可用),其余四套完全平面、阶梯像素动效、内容列宽随视口撑开;宿主侧记忆主题选择,桌面端 dsh-app:// 也能恢复",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "files": [
8
+ "lib",
9
+ "assets",
10
+ "cordis.patch.yml",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "exports": {
15
+ ".": "./lib/index.js",
16
+ "./client": "./lib/client.js",
17
+ "./package.json": "./package.json"
18
+ },
19
+ "scripts": {
20
+ "build": "node scripts/build.mjs",
21
+ "test": "node scripts/check-compat.mjs && node scripts/test-host.mjs && node scripts/test-client.mjs && node scripts/audit-contrast.mjs",
22
+ "test:compat": "node scripts/check-compat.mjs",
23
+ "test:host": "node scripts/test-host.mjs",
24
+ "test:client": "node scripts/test-client.mjs",
25
+ "test:contrast": "node scripts/audit-contrast.mjs"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/zhang66633/dsh-pixel-ui.git"
30
+ },
31
+ "keywords": [
32
+ "dsh",
33
+ "dsh-plugin",
34
+ "deepseek-harness",
35
+ "theme",
36
+ "skin",
37
+ "pixel",
38
+ "retro",
39
+ "ui"
40
+ ],
41
+ "engines": {
42
+ "dsh": ">=0.1.0-rc.6 <0.2.0-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0"
43
+ },
44
+ "dsh": {
45
+ "bundle": {
46
+ "patch": "./cordis.patch.yml"
47
+ },
48
+ "client": {
49
+ "inject": [
50
+ "@deepseek-ai/dsh-client-ui-theme",
51
+ "@deepseek-ai/dsh-client-ui-slots",
52
+ "@deepseek-ai/dsh-client-ui-settings-general"
53
+ ],
54
+ "platform": "web"
55
+ },
56
+ "compatibility": {
57
+ "dsh": ">=0.1.0-rc.6 <0.3.0-0",
58
+ "dshReleases": {
59
+ "0.1.0-rc.6": "compatible",
60
+ "0.1.0-rc.7": "compatible",
61
+ "0.1.7-rc.2": "compatible",
62
+ "0.2.0-rc.1": "compatible",
63
+ "0.2.0-rc.2": "compatible",
64
+ "0.2.1-rc.3": "compatible"
65
+ }
66
+ }
67
+ },
68
+ "peerDependencies": {
69
+ "@deepseek-ai/cordis": "^4.0.1",
70
+ "@deepseek-ai/dsh-client-store": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
71
+ "@deepseek-ai/dsh-client-ui-theme": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
72
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
73
+ "@deepseek-ai/dsh-client-ui-settings-general": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0",
74
+ "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.3-0 || ^0.1.5-0 || >=0.2.0-rc.1 <0.3.0-0 || >=0.2.1-0 <0.3.0-0"
75
+ },
76
+ "devDependencies": {
77
+ "esbuild": "^0.28.2",
78
+ "semver": "^7.8.5"
79
+ },
80
+ "license": "MIT"
81
+ }